DFG JIT cannot compile op_new_object, op_new_array,
[WebKit.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #include "DFGSpeculativeJIT.h"
29
30 #if ENABLE(DFG_JIT)
31 #if USE(JSVALUE64)
32
33 namespace JSC { namespace DFG {
34
35 template<bool strict>
36 GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat)
37 {
38 #if ENABLE(DFG_DEBUG_VERBOSE)
39     fprintf(stderr, "SpecInt@%d   ", nodeIndex);
40 #endif
41     Node& node = m_jit.graph()[nodeIndex];
42     VirtualRegister virtualRegister = node.virtualRegister();
43     GenerationInfo& info = m_generationInfo[virtualRegister];
44
45     switch (info.registerFormat()) {
46     case DataFormatNone: {
47         if (node.hasConstant() && !isInt32Constant(nodeIndex)) {
48             terminateSpeculativeExecution();
49             returnFormat = DataFormatInteger;
50             return allocate();
51         }
52         
53         GPRReg gpr = allocate();
54
55         if (node.hasConstant()) {
56             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
57             ASSERT(isInt32Constant(nodeIndex));
58             m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
59             info.fillInteger(gpr);
60             returnFormat = DataFormatInteger;
61             return gpr;
62         }
63         
64         DataFormat spillFormat = info.spillFormat();
65         ASSERT(spillFormat & DataFormatJS);
66         
67         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
68         
69         if (spillFormat == DataFormatJSInteger) {
70             // If we know this was spilled as an integer we can fill without checking.
71             if (strict) {
72                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
73                 info.fillInteger(gpr);
74                 returnFormat = DataFormatInteger;
75                 return gpr;
76             }
77             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
78             info.fillJSValue(gpr, DataFormatJSInteger);
79             returnFormat = DataFormatJSInteger;
80             return gpr;
81         }
82         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
83
84         // Fill as JSValue, and fall through.
85         info.fillJSValue(gpr, DataFormatJSInteger);
86         m_gprs.unlock(gpr);
87     }
88
89     case DataFormatJS: {
90         // Check the value is an integer.
91         GPRReg gpr = info.gpr();
92         m_gprs.lock(gpr);
93         speculationCheck(m_jit.branchPtr(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));
94         info.fillJSValue(gpr, DataFormatJSInteger);
95         // If !strict we're done, return.
96         if (!strict) {
97             returnFormat = DataFormatJSInteger;
98             return gpr;
99         }
100         // else fall through & handle as DataFormatJSInteger.
101         m_gprs.unlock(gpr);
102     }
103
104     case DataFormatJSInteger: {
105         // In a strict fill we need to strip off the value tag.
106         if (strict) {
107             GPRReg gpr = info.gpr();
108             GPRReg result;
109             // If the register has already been locked we need to take a copy.
110             // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
111             if (m_gprs.isLocked(gpr))
112                 result = allocate();
113             else {
114                 m_gprs.lock(gpr);
115                 info.fillInteger(gpr);
116                 result = gpr;
117             }
118             m_jit.zeroExtend32ToPtr(gpr, result);
119             returnFormat = DataFormatInteger;
120             return result;
121         }
122
123         GPRReg gpr = info.gpr();
124         m_gprs.lock(gpr);
125         returnFormat = DataFormatJSInteger;
126         return gpr;
127     }
128
129     case DataFormatInteger: {
130         GPRReg gpr = info.gpr();
131         m_gprs.lock(gpr);
132         returnFormat = DataFormatInteger;
133         return gpr;
134     }
135
136     case DataFormatDouble:
137     case DataFormatCell:
138     case DataFormatBoolean:
139     case DataFormatJSDouble:
140     case DataFormatJSCell:
141     case DataFormatJSBoolean: {
142         terminateSpeculativeExecution();
143         returnFormat = DataFormatInteger;
144         return allocate();
145     }
146         
147     case DataFormatStorage:
148         ASSERT_NOT_REACHED();
149     }
150
151     ASSERT_NOT_REACHED();
152     return InvalidGPRReg;
153 }
154
155 #ifndef NDEBUG
156 void ValueSource::dump(FILE* out) const
157 {
158     fprintf(out, "Node(%d)", m_nodeIndex);
159 }
160
161 void ValueRecovery::dump(FILE* out) const
162 {
163     switch (technique()) {
164     case AlreadyInRegisterFile:
165         fprintf(out, "-");
166         break;
167     case AlreadyInRegisterFileAsUnboxedInt32:
168         fprintf(out, "(int32)");
169         break;
170     case InGPR:
171         fprintf(out, "%%%s", GPRInfo::debugName(gpr()));
172         break;
173     case UnboxedInt32InGPR:
174         fprintf(out, "int32(%%%s)", GPRInfo::debugName(gpr()));
175         break;
176     case InFPR:
177         fprintf(out, "%%%s", FPRInfo::debugName(fpr()));
178         break;
179     case DisplacedInRegisterFile:
180         fprintf(out, "*%d", virtualRegister());
181         break;
182     case Constant:
183         fprintf(out, "[%s]", constant().description());
184         break;
185     case DontKnow:
186         fprintf(out, "!");
187         break;
188     default:
189         fprintf(out, "?%d", technique());
190         break;
191     }
192 }
193 #endif
194
195 OSRExit::OSRExit(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex)
196     : m_check(check)
197     , m_nodeIndex(jit->m_compileIndex)
198     , m_bytecodeIndex(jit->m_bytecodeIndexForOSR)
199     , m_recoveryIndex(recoveryIndex)
200     , m_arguments(jit->m_arguments.size())
201     , m_variables(jit->m_variables.size())
202     , m_lastSetOperand(jit->m_lastSetOperand)
203 {
204     ASSERT(m_bytecodeIndex != std::numeric_limits<uint32_t>::max());
205     for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
206         m_arguments[argument] = jit->computeValueRecoveryFor(operandForArgument(argument), jit->m_arguments[argument]);
207     for (unsigned variable = 0; variable < m_variables.size(); ++variable)
208         m_variables[variable] = jit->computeValueRecoveryFor(variable, jit->m_variables[variable]);
209 }
210
211 #ifndef NDEBUG
212 void OSRExit::dump(FILE* out) const
213 {
214     for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
215         m_arguments[argument].dump(out);
216     fprintf(out, " : ");
217     for (unsigned variable = 0; variable < m_variables.size(); ++variable)
218         m_variables[variable].dump(out);
219 }
220 #endif
221
222 GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat)
223 {
224     return fillSpeculateIntInternal<false>(nodeIndex, returnFormat);
225 }
226
227 GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
228 {
229     DataFormat mustBeDataFormatInteger;
230     GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger);
231     ASSERT(mustBeDataFormatInteger == DataFormatInteger);
232     return result;
233 }
234
235 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
236 {
237 #if ENABLE(DFG_DEBUG_VERBOSE)
238     fprintf(stderr, "SpecDouble@%d   ", nodeIndex);
239 #endif
240     Node& node = m_jit.graph()[nodeIndex];
241     VirtualRegister virtualRegister = node.virtualRegister();
242     GenerationInfo& info = m_generationInfo[virtualRegister];
243
244     if (info.registerFormat() == DataFormatNone) {
245         GPRReg gpr = allocate();
246
247         if (node.hasConstant()) {
248             if (isInt32Constant(nodeIndex)) {
249                 FPRReg fpr = fprAllocate();
250                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(static_cast<double>(valueOfInt32Constant(nodeIndex))))), gpr);
251                 m_jit.movePtrToDouble(gpr, fpr);
252                 unlock(gpr);
253
254                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
255                 info.fillDouble(fpr);
256                 return fpr;
257             }
258             if (isNumberConstant(nodeIndex)) {
259                 FPRReg fpr = fprAllocate();
260                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(nodeIndex)))), gpr);
261                 m_jit.movePtrToDouble(gpr, fpr);
262                 unlock(gpr);
263
264                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
265                 info.fillDouble(fpr);
266                 return fpr;
267             }
268             terminateSpeculativeExecution();
269             return fprAllocate();
270         }
271         
272         DataFormat spillFormat = info.spillFormat();
273         ASSERT(spillFormat & DataFormatJS);
274         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
275         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
276         info.fillJSValue(gpr, spillFormat);
277         unlock(gpr);
278     }
279
280     switch (info.registerFormat()) {
281     case DataFormatNone: // Should have filled, above.
282     case DataFormatBoolean: // This type never occurs.
283     case DataFormatStorage:
284         ASSERT_NOT_REACHED();
285         
286     case DataFormatCell:
287     case DataFormatJSCell:
288     case DataFormatJS:
289     case DataFormatJSBoolean: {
290         GPRReg jsValueGpr = info.gpr();
291         m_gprs.lock(jsValueGpr);
292         FPRReg fpr = fprAllocate();
293         GPRReg tempGpr = allocate();
294
295         JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
296
297         speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
298
299         // First, if we get here we have a double encoded as a JSValue
300         m_jit.move(jsValueGpr, tempGpr);
301         unboxDouble(tempGpr, fpr);
302         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
303
304         // Finally, handle integers.
305         isInteger.link(&m_jit);
306         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
307         hasUnboxedDouble.link(&m_jit);
308
309         m_gprs.release(jsValueGpr);
310         m_gprs.unlock(jsValueGpr);
311         m_gprs.unlock(tempGpr);
312         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
313         info.fillDouble(fpr);
314         info.killSpilled();
315         return fpr;
316     }
317
318     case DataFormatJSInteger:
319     case DataFormatInteger: {
320         FPRReg fpr = fprAllocate();
321         GPRReg gpr = info.gpr();
322         m_gprs.lock(gpr);
323         m_jit.convertInt32ToDouble(gpr, fpr);
324         m_gprs.unlock(gpr);
325         return fpr;
326     }
327
328     // Unbox the double
329     case DataFormatJSDouble: {
330         GPRReg gpr = info.gpr();
331         FPRReg fpr = fprAllocate();
332         if (m_gprs.isLocked(gpr)) {
333             // Make sure we don't trample gpr if it is in use.
334             GPRReg temp = allocate();
335             m_jit.move(gpr, temp);
336             unboxDouble(temp, fpr);
337             unlock(temp);
338         } else
339             unboxDouble(gpr, fpr);
340
341         m_gprs.release(gpr);
342         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
343
344         info.fillDouble(fpr);
345         return fpr;
346     }
347
348     case DataFormatDouble: {
349         FPRReg fpr = info.fpr();
350         m_fprs.lock(fpr);
351         return fpr;
352     }
353     }
354
355     ASSERT_NOT_REACHED();
356     return InvalidFPRReg;
357 }
358
359 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
360 {
361 #if ENABLE(DFG_DEBUG_VERBOSE)
362     fprintf(stderr, "SpecCell@%d   ", nodeIndex);
363 #endif
364     Node& node = m_jit.graph()[nodeIndex];
365     VirtualRegister virtualRegister = node.virtualRegister();
366     GenerationInfo& info = m_generationInfo[virtualRegister];
367
368     switch (info.registerFormat()) {
369     case DataFormatNone: {
370         GPRReg gpr = allocate();
371
372         if (node.hasConstant()) {
373             JSValue jsValue = valueOfJSConstant(nodeIndex);
374             if (jsValue.isCell()) {
375                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
376                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
377                 info.fillJSValue(gpr, DataFormatJSCell);
378                 return gpr;
379             }
380             terminateSpeculativeExecution();
381             return gpr;
382         }
383         ASSERT(info.spillFormat() & DataFormatJS);
384         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
385         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
386
387         info.fillJSValue(gpr, DataFormatJS);
388         if (info.spillFormat() != DataFormatJSCell)
389             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
390         info.fillJSValue(gpr, DataFormatJSCell);
391         return gpr;
392     }
393
394     case DataFormatCell:
395     case DataFormatJSCell: {
396         GPRReg gpr = info.gpr();
397         m_gprs.lock(gpr);
398         return gpr;
399     }
400
401     case DataFormatJS: {
402         GPRReg gpr = info.gpr();
403         m_gprs.lock(gpr);
404         speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
405         info.fillJSValue(gpr, DataFormatJSCell);
406         return gpr;
407     }
408
409     case DataFormatJSInteger:
410     case DataFormatInteger:
411     case DataFormatJSDouble:
412     case DataFormatDouble:
413     case DataFormatJSBoolean:
414     case DataFormatBoolean: {
415         terminateSpeculativeExecution();
416         return allocate();
417     }
418         
419     case DataFormatStorage:
420         ASSERT_NOT_REACHED();
421     }
422
423     ASSERT_NOT_REACHED();
424     return InvalidGPRReg;
425 }
426
427 GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex)
428 {
429 #if ENABLE(DFG_DEBUG_VERBOSE)
430     fprintf(stderr, "SpecBool@%d   ", nodeIndex);
431 #endif
432     Node& node = m_jit.graph()[nodeIndex];
433     VirtualRegister virtualRegister = node.virtualRegister();
434     GenerationInfo& info = m_generationInfo[virtualRegister];
435
436     switch (info.registerFormat()) {
437     case DataFormatNone: {
438         GPRReg gpr = allocate();
439
440         if (node.hasConstant()) {
441             JSValue jsValue = valueOfJSConstant(nodeIndex);
442             if (jsValue.isBoolean()) {
443                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
444                 m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
445                 info.fillJSValue(gpr, DataFormatJSBoolean);
446                 return gpr;
447             }
448             terminateSpeculativeExecution();
449             return gpr;
450         }
451         ASSERT(info.spillFormat() & DataFormatJS);
452         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
453         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
454
455         info.fillJSValue(gpr, DataFormatJS);
456         if (info.spillFormat() != DataFormatJSBoolean) {
457             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
458             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
459             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
460         }
461         info.fillJSValue(gpr, DataFormatJSBoolean);
462         return gpr;
463     }
464
465     case DataFormatBoolean:
466     case DataFormatJSBoolean: {
467         GPRReg gpr = info.gpr();
468         m_gprs.lock(gpr);
469         return gpr;
470     }
471
472     case DataFormatJS: {
473         GPRReg gpr = info.gpr();
474         m_gprs.lock(gpr);
475         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
476         speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
477         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
478         info.fillJSValue(gpr, DataFormatJSBoolean);
479         return gpr;
480     }
481
482     case DataFormatJSInteger:
483     case DataFormatInteger:
484     case DataFormatJSDouble:
485     case DataFormatDouble:
486     case DataFormatJSCell:
487     case DataFormatCell: {
488         terminateSpeculativeExecution();
489         return allocate();
490     }
491         
492     case DataFormatStorage:
493         ASSERT_NOT_REACHED();
494     }
495
496     ASSERT_NOT_REACHED();
497     return InvalidGPRReg;
498 }
499
500 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition)
501 {
502     Node& branchNode = m_jit.graph()[branchNodeIndex];
503     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
504     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
505
506     // The branch instruction will branch to the taken block.
507     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
508     if (taken == (m_block + 1)) {
509         condition = JITCompiler::invert(condition);
510         BlockIndex tmp = taken;
511         taken = notTaken;
512         notTaken = tmp;
513     }
514
515     if (isInt32Constant(node.child1())) {
516         int32_t imm = valueOfInt32Constant(node.child1());
517         SpeculateIntegerOperand op2(this, node.child2());
518         addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
519     } else if (isInt32Constant(node.child2())) {
520         SpeculateIntegerOperand op1(this, node.child1());
521         int32_t imm = valueOfInt32Constant(node.child2());
522         addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
523     } else {
524         SpeculateIntegerOperand op1(this, node.child1());
525         SpeculateIntegerOperand op2(this, node.child2());
526         addBranch(m_jit.branch32(condition, op1.gpr(), op2.gpr()), taken);
527     }
528
529     // Check for fall through, otherwise we need to jump.
530     if (notTaken != (m_block + 1))
531         addBranch(m_jit.jump(), notTaken);
532 }
533
534 JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, GPRReg tmp)
535 {
536     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, value, GPRInfo::tagTypeNumberRegister);
537     
538     JITCompiler::Jump notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, value, GPRInfo::tagTypeNumberRegister);
539     
540     m_jit.move(value, tmp);
541     unboxDouble(tmp, result);
542     
543     JITCompiler::Jump done = m_jit.jump();
544     
545     isInteger.link(&m_jit);
546     
547     m_jit.convertInt32ToDouble(value, result);
548     
549     done.link(&m_jit);
550
551     return notNumber;
552 }
553
554 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
555 {
556     Node& branchNode = m_jit.graph()[branchNodeIndex];
557     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
558     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
559     
560     SpeculateDoubleOperand op1(this, node.child1());
561     SpeculateDoubleOperand op2(this, node.child2());
562     
563     addBranch(m_jit.branchDouble(condition, op1.fpr(), op2.fpr()), taken);
564     
565     if (notTaken != (m_block + 1))
566         addBranch(m_jit.jump(), notTaken);
567 }
568
569 void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, void* vptr)
570 {
571     Node& branchNode = m_jit.graph()[branchNodeIndex];
572     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
573     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
574
575     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
576     
577     if (taken == (m_block + 1)) {
578         condition = MacroAssembler::NotEqual;
579         BlockIndex tmp = taken;
580         taken = notTaken;
581         notTaken = tmp;
582     }
583
584     SpeculateCellOperand op1(this, node.child1());
585     SpeculateCellOperand op2(this, node.child2());
586     
587     GPRReg op1GPR = op1.gpr();
588     GPRReg op2GPR = op2.gpr();
589     
590     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
591     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
592     
593     addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken);
594     if (notTaken != (m_block + 1))
595         addBranch(m_jit.jump(), notTaken);
596 }
597
598 void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr)
599 {
600     SpeculateCellOperand op1(this, node.child1());
601     SpeculateCellOperand op2(this, node.child2());
602     GPRTemporary result(this, op1);
603     
604     GPRReg op1GPR = op1.gpr();
605     GPRReg op2GPR = op2.gpr();
606     GPRReg resultGPR = result.gpr();
607     
608     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
609     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
610     
611     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
612     m_jit.move(Imm32(ValueTrue), resultGPR);
613     MacroAssembler::Jump done = m_jit.jump();
614     falseCase.link(&m_jit);
615     m_jit.move(Imm32(ValueFalse), resultGPR);
616     done.link(&m_jit);
617
618     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
619 }
620
621 // Returns true if the compare is fused with a subsequent branch.
622 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
623 {
624     // Fused compare & branch.
625     NodeIndex branchNodeIndex = detectPeepHoleBranch();
626     if (branchNodeIndex != NoNode) {
627         // detectPeepHoleBranch currently only permits the branch to be the very next node,
628         // so can be no intervening nodes to also reference the compare. 
629         ASSERT(node.adjustedRefCount() == 1);
630
631         if (shouldSpeculateInteger(node.child1(), node.child2())) {
632             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
633             use(node.child1());
634             use(node.child2());
635         } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
636             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
637             use(node.child1());
638             use(node.child2());
639         } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
640             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
641             use(node.child1());
642             use(node.child2());
643         } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
644             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
645             use(node.child1());
646             use(node.child2());
647         } else
648             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
649
650         m_compileIndex = branchNodeIndex;
651         return true;
652     }
653     
654     if (shouldSpeculateFinalObject(node.child1(), node.child2()))
655         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr);
656     else if (shouldSpeculateArray(node.child1(), node.child2()))
657         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr);
658     else if (!shouldSpeculateNumber(node.child1()) && !shouldSpeculateNumber(node.child2()))
659         nonSpeculativeNonPeepholeCompare(node, condition, operation);
660     else if ((shouldSpeculateNumber(node.child1()) || shouldSpeculateNumber(node.child2())) && !shouldSpeculateInteger(node.child1(), node.child2())) {
661         // Normal case, not fused to branch.
662         SpeculateDoubleOperand op1(this, node.child1());
663         SpeculateDoubleOperand op2(this, node.child2());
664         GPRTemporary result(this);
665         
666         m_jit.move(TrustedImm32(ValueTrue), result.gpr());
667         MacroAssembler::Jump trueCase = m_jit.branchDouble(doubleCondition, op1.fpr(), op2.fpr());
668         m_jit.xorPtr(Imm32(true), result.gpr());
669         trueCase.link(&m_jit);
670
671         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
672     } else {
673         // Normal case, not fused to branch.
674         SpeculateIntegerOperand op1(this, node.child1());
675         SpeculateIntegerOperand op2(this, node.child2());
676         GPRTemporary result(this, op1, op2);
677         
678         m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
679         
680         // If we add a DataFormatBool, we should use it here.
681         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
682         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
683     }
684     
685     return false;
686 }
687
688 template<typename T>
689 void SpeculativeJIT::emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
690 {
691     MarkedSpace::SizeClass* sizeClass = &m_jit.globalData()->heap.sizeClassForObject(sizeof(JSFinalObject));
692     
693     m_jit.loadPtr(&sizeClass->firstFreeCell, resultGPR);
694     slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
695     
696     // The object is half-allocated: we have what we know is a fresh object, but
697     // it's still on the GC's free list.
698     
699     // Ditch the structure by placing it into the structure slot, so that we can reuse
700     // scratchGPR.
701     m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSObject::structureOffset()));
702     
703     // Now that we have scratchGPR back, remove the object from the free list
704     m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
705     m_jit.storePtr(scratchGPR, &sizeClass->firstFreeCell);
706     
707     // Initialize the object's vtable
708     m_jit.storePtr(MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr), MacroAssembler::Address(resultGPR));
709     
710     // Initialize the object's inheritorID.
711     m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::offsetOfInheritorID()));
712     
713     // Initialize the object's property storage pointer.
714     m_jit.addPtr(MacroAssembler::TrustedImm32(sizeof(JSObject)), resultGPR, scratchGPR);
715     m_jit.storePtr(scratchGPR, MacroAssembler::Address(resultGPR, JSFinalObject::offsetOfPropertyStorage()));
716 }
717
718 void SpeculativeJIT::compile(Node& node)
719 {
720     NodeType op = node.op;
721
722     switch (op) {
723     case JSConstant:
724         initConstantInfo(m_compileIndex);
725         break;
726
727     case GetLocal: {
728         PredictedType prediction = m_jit.graph().getPrediction(node.local());
729
730         // If we have no prediction for this local, then don't attempt to compile.
731         if (prediction == PredictNone) {
732             terminateSpeculativeExecution();
733             break;
734         }
735         
736         GPRTemporary result(this);
737         if (isInt32Prediction(prediction)) {
738             m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
739
740             // Like integerResult, but don't useChildren - our children are phi nodes,
741             // and don't represent values within this dataflow with virtual registers.
742             VirtualRegister virtualRegister = node.virtualRegister();
743             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
744             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
745         } else {
746             m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
747
748             // Like jsValueResult, but don't useChildren - our children are phi nodes,
749             // and don't represent values within this dataflow with virtual registers.
750             VirtualRegister virtualRegister = node.virtualRegister();
751             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
752             
753             DataFormat format;
754             if (isArrayPrediction(prediction))
755                 format = DataFormatJSCell;
756             else if (isBooleanPrediction(prediction))
757                 format = DataFormatJSBoolean;
758             else
759                 format = DataFormatJS;
760             
761             m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
762         }
763         break;
764     }
765
766     case SetLocal: {
767         // SetLocal doubles as a hint as to where a node will be stored and
768         // as a speculation point. So before we speculate make sure that we
769         // know where the child of this node needs to go in the virtual
770         // register file.
771         compileMovHint(node);
772         
773         // As far as OSR is concerned, we're on the bytecode index corresponding
774         // to the *next* instruction, since we've already "executed" the
775         // SetLocal and whatever other DFG Nodes are associated with the same
776         // bytecode index as the SetLocal.
777         ASSERT(m_bytecodeIndexForOSR == node.codeOrigin.bytecodeIndex());
778         Node& nextNode = m_jit.graph()[m_compileIndex+1];
779         
780         // This assertion will fail if we ever emit multiple SetLocal's for
781         // a single bytecode instruction. That's unlikely to happen. But if
782         // it does, the solution is to to have this perform a search until
783         // it finds a Node with a different bytecode index from the one we've
784         // got, and to abstractly execute the SetLocal's along the way. Or,
785         // better yet, handle all of the SetLocal's at once: abstract interpret
786         // all of them, then emit code for all of them, with OSR exiting to
787         // the next non-SetLocal instruction. Note the special case for when
788         // both this SetLocal and the next op have a bytecode index of 0; this
789         // occurs for SetLocal's generated at the top of the code block to
790         // initialize locals to undefined. Ideally, we'd have a way of marking
791         // in the CodeOrigin that a SetLocal is synthetic. This will make the
792         // assertion more sensible-looking. We should then also assert that
793         // synthetic SetLocal's don't have speculation checks, since they
794         // should only be dropping values that we statically know we are
795         // allowed to drop into the variables. DFGPropagator will guarantee
796         // this, since it should have at least an approximation (if not
797         // exact knowledge) of the type of the SetLocal's child node, and
798         // should merge that information into the local that is being set.
799         ASSERT(m_bytecodeIndexForOSR != nextNode.codeOrigin.bytecodeIndex()
800                || (!m_bytecodeIndexForOSR && !nextNode.codeOrigin.bytecodeIndex()));
801         m_bytecodeIndexForOSR = nextNode.codeOrigin.bytecodeIndex();
802         
803         PredictedType predictedType = m_jit.graph().getPrediction(node.local());
804         if (isInt32Prediction(predictedType)) {
805             SpeculateIntegerOperand value(this, node.child1());
806             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
807             noResult(m_compileIndex);
808         } else if (isArrayPrediction(predictedType)) {
809             SpeculateCellOperand cell(this, node.child1());
810             GPRReg cellGPR = cell.gpr();
811             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
812             m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
813             noResult(m_compileIndex);
814         } else if (isBooleanPrediction(predictedType)) {
815             SpeculateBooleanOperand boolean(this, node.child1());
816             m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local()));
817             noResult(m_compileIndex);
818         } else {
819             JSValueOperand value(this, node.child1());
820             m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
821             noResult(m_compileIndex);
822         }
823         
824         // Indicate that it's no longer necessary to retrieve the value of
825         // this bytecode variable from registers or other locations in the register file.
826         valueSourceReferenceForOperand(node.local()) = ValueSource();
827         break;
828     }
829
830     case BitAnd:
831     case BitOr:
832     case BitXor:
833         if (isInt32Constant(node.child1())) {
834             SpeculateIntegerOperand op2(this, node.child2());
835             GPRTemporary result(this, op2);
836
837             bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
838
839             integerResult(result.gpr(), m_compileIndex);
840         } else if (isInt32Constant(node.child2())) {
841             SpeculateIntegerOperand op1(this, node.child1());
842             GPRTemporary result(this, op1);
843
844             bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
845
846             integerResult(result.gpr(), m_compileIndex);
847         } else {
848             SpeculateIntegerOperand op1(this, node.child1());
849             SpeculateIntegerOperand op2(this, node.child2());
850             GPRTemporary result(this, op1, op2);
851
852             GPRReg reg1 = op1.gpr();
853             GPRReg reg2 = op2.gpr();
854             bitOp(op, reg1, reg2, result.gpr());
855
856             integerResult(result.gpr(), m_compileIndex);
857         }
858         break;
859
860     case BitRShift:
861     case BitLShift:
862     case BitURShift:
863         if (isInt32Constant(node.child2())) {
864             SpeculateIntegerOperand op1(this, node.child1());
865             GPRTemporary result(this, op1);
866
867             shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
868
869             integerResult(result.gpr(), m_compileIndex);
870         } else {
871             // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
872             SpeculateIntegerOperand op1(this, node.child1());
873             SpeculateIntegerOperand op2(this, node.child2());
874             GPRTemporary result(this, op1);
875
876             GPRReg reg1 = op1.gpr();
877             GPRReg reg2 = op2.gpr();
878             shiftOp(op, reg1, reg2, result.gpr());
879
880             integerResult(result.gpr(), m_compileIndex);
881         }
882         break;
883
884     case UInt32ToNumber: {
885         if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
886             // We know that this sometimes produces doubles. So produce a double every
887             // time. This at least allows subsequent code to not have weird conditionals.
888             
889             IntegerOperand op1(this, node.child1());
890             FPRTemporary result(this);
891             
892             GPRReg inputGPR = op1.gpr();
893             FPRReg outputFPR = result.fpr();
894             
895             m_jit.convertInt32ToDouble(inputGPR, outputFPR);
896             
897             JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
898             m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR);
899             positive.link(&m_jit);
900             
901             doubleResult(outputFPR, m_compileIndex);
902         }
903         
904         IntegerOperand op1(this, node.child1());
905         GPRTemporary result(this, op1);
906
907         // Test the operand is positive.
908         speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));
909
910         m_jit.move(op1.gpr(), result.gpr());
911         integerResult(result.gpr(), m_compileIndex, op1.format());
912         break;
913     }
914         
915     case ValueToInt32: {
916         if (shouldNotSpeculateInteger(node.child1())) {
917             // Do it the safe way.
918             nonSpeculativeValueToInt32(node);
919             break;
920         }
921         
922         if (shouldNotSpeculateInteger(node.child1())) {
923             // Do it the safe way.
924             nonSpeculativeValueToInt32(node);
925             break;
926         }
927         
928         SpeculateIntegerOperand op1(this, node.child1());
929         GPRTemporary result(this, op1);
930         m_jit.move(op1.gpr(), result.gpr());
931         integerResult(result.gpr(), m_compileIndex, op1.format());
932         break;
933     }
934
935     case ValueToNumber: {
936         if (shouldNotSpeculateInteger(node.child1())) {
937             SpeculateDoubleOperand op1(this, node.child1());
938             FPRTemporary result(this, op1);
939             m_jit.moveDouble(op1.fpr(), result.fpr());
940             doubleResult(result.fpr(), m_compileIndex);
941             break;
942         }
943         
944         SpeculateIntegerOperand op1(this, node.child1());
945         GPRTemporary result(this, op1);
946         m_jit.move(op1.gpr(), result.gpr());
947         integerResult(result.gpr(), m_compileIndex, op1.format());
948         break;
949     }
950
951     case ValueToDouble: {
952         SpeculateDoubleOperand op1(this, node.child1());
953         FPRTemporary result(this, op1);
954         m_jit.moveDouble(op1.fpr(), result.fpr());
955         doubleResult(result.fpr(), m_compileIndex);
956         break;
957     }
958
959     case ValueAdd:
960     case ArithAdd: {
961         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
962             if (isInt32Constant(node.child1())) {
963                 int32_t imm1 = valueOfInt32Constant(node.child1());
964                 SpeculateIntegerOperand op2(this, node.child2());
965                 GPRTemporary result(this);
966                 
967                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
968                     m_jit.move(op2.gpr(), result.gpr());
969                     m_jit.add32(Imm32(imm1), result.gpr());
970                 } else
971                     speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
972
973                 integerResult(result.gpr(), m_compileIndex);
974                 break;
975             }
976                 
977             if (isInt32Constant(node.child2())) {
978                 SpeculateIntegerOperand op1(this, node.child1());
979                 int32_t imm2 = valueOfInt32Constant(node.child2());
980                 GPRTemporary result(this);
981                 
982                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
983                     m_jit.move(op1.gpr(), result.gpr());
984                     m_jit.add32(Imm32(imm2), result.gpr());
985                 } else
986                     speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
987
988                 integerResult(result.gpr(), m_compileIndex);
989                 break;
990             }
991                 
992             SpeculateIntegerOperand op1(this, node.child1());
993             SpeculateIntegerOperand op2(this, node.child2());
994             GPRTemporary result(this, op1, op2);
995
996             GPRReg gpr1 = op1.gpr();
997             GPRReg gpr2 = op2.gpr();
998             GPRReg gprResult = result.gpr();
999             
1000             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
1001                 if (gpr1 == gprResult)
1002                     m_jit.add32(gpr2, gprResult);
1003                 else {
1004                     m_jit.move(gpr2, gprResult);
1005                     m_jit.add32(gpr1, gprResult);
1006                 }
1007             } else {
1008                 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
1009                 
1010                 if (gpr1 == gprResult)
1011                     speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
1012                 else if (gpr2 == gprResult)
1013                     speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
1014                 else
1015                     speculationCheck(check);
1016             }
1017
1018             integerResult(gprResult, m_compileIndex);
1019             break;
1020         }
1021         
1022         if (shouldSpeculateNumber(node.child1(), node.child2())) {
1023             SpeculateDoubleOperand op1(this, node.child1());
1024             SpeculateDoubleOperand op2(this, node.child2());
1025             FPRTemporary result(this, op1, op2);
1026             
1027             FPRReg reg1 = op1.fpr();
1028             FPRReg reg2 = op2.fpr();
1029             m_jit.addDouble(reg1, reg2, result.fpr());
1030             
1031             doubleResult(result.fpr(), m_compileIndex);
1032             break;
1033         }
1034         
1035         ASSERT(op == ValueAdd);
1036         
1037         JSValueOperand op1(this, node.child1());
1038         JSValueOperand op2(this, node.child2());
1039         
1040         GPRReg op1GPR = op1.gpr();
1041         GPRReg op2GPR = op2.gpr();
1042         
1043         flushRegisters();
1044         
1045         GPRResult result(this);
1046         if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
1047             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
1048         else
1049             callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
1050         
1051         jsValueResult(result.gpr(), m_compileIndex);
1052         break;
1053     }
1054
1055     case ArithSub: {
1056         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1057             if (isInt32Constant(node.child2())) {
1058                 SpeculateIntegerOperand op1(this, node.child1());
1059                 int32_t imm2 = valueOfInt32Constant(node.child2());
1060                 GPRTemporary result(this);
1061
1062                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
1063                     m_jit.move(op1.gpr(), result.gpr());
1064                     m_jit.sub32(Imm32(imm2), result.gpr());
1065                 } else
1066                     speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
1067
1068                 integerResult(result.gpr(), m_compileIndex);
1069                 break;
1070             }
1071                 
1072             SpeculateIntegerOperand op1(this, node.child1());
1073             SpeculateIntegerOperand op2(this, node.child2());
1074             GPRTemporary result(this);
1075
1076             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
1077                 m_jit.move(op1.gpr(), result.gpr());
1078                 m_jit.sub32(op2.gpr(), result.gpr());
1079             } else
1080                 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
1081
1082             integerResult(result.gpr(), m_compileIndex);
1083             break;
1084         }
1085         
1086         SpeculateDoubleOperand op1(this, node.child1());
1087         SpeculateDoubleOperand op2(this, node.child2());
1088         FPRTemporary result(this, op1);
1089
1090         FPRReg reg1 = op1.fpr();
1091         FPRReg reg2 = op2.fpr();
1092         m_jit.subDouble(reg1, reg2, result.fpr());
1093
1094         doubleResult(result.fpr(), m_compileIndex);
1095         break;
1096     }
1097
1098     case ArithMul: {
1099         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1100             SpeculateIntegerOperand op1(this, node.child1());
1101             SpeculateIntegerOperand op2(this, node.child2());
1102             GPRTemporary result(this);
1103
1104             GPRReg reg1 = op1.gpr();
1105             GPRReg reg2 = op2.gpr();
1106             
1107             // What is unfortunate is that we cannot take advantage of nodeCanTruncateInteger()
1108             // here. A multiply on integers performed in the double domain and then truncated to
1109             // an integer will give a different result than a multiply performed in the integer
1110             // domain and then truncated, if the integer domain result would have resulted in
1111             // something bigger than what a 32-bit integer can hold. JavaScript mandates that
1112             // the semantics are always as if the multiply had been performed in the double
1113             // domain.
1114             
1115             speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
1116             
1117             // Check for negative zero, if the users of this node care about such things.
1118             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
1119                 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
1120                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
1121                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
1122                 resultNonZero.link(&m_jit);
1123             }
1124
1125             integerResult(result.gpr(), m_compileIndex);
1126             break;
1127         }
1128         
1129         SpeculateDoubleOperand op1(this, node.child1());
1130         SpeculateDoubleOperand op2(this, node.child2());
1131         FPRTemporary result(this, op1, op2);
1132
1133         FPRReg reg1 = op1.fpr();
1134         FPRReg reg2 = op2.fpr();
1135         
1136         m_jit.mulDouble(reg1, reg2, result.fpr());
1137         
1138         doubleResult(result.fpr(), m_compileIndex);
1139         break;
1140     }
1141
1142     case ArithDiv: {
1143         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1144             SpeculateIntegerOperand op1(this, node.child1());
1145             SpeculateIntegerOperand op2(this, node.child2());
1146             GPRTemporary eax(this, X86Registers::eax);
1147             GPRTemporary edx(this, X86Registers::edx);
1148             GPRReg op1GPR = op1.gpr();
1149             GPRReg op2GPR = op2.gpr();
1150             
1151             speculationCheck(m_jit.branchTest32(JITCompiler::Zero, op2GPR));
1152             
1153             // If the user cares about negative zero, then speculate that we're not about
1154             // to produce negative zero.
1155             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
1156                 MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
1157                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
1158                 numeratorNonZero.link(&m_jit);
1159             }
1160             
1161             GPRReg temp2 = InvalidGPRReg;
1162             if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
1163                 temp2 = allocate();
1164                 m_jit.move(op2GPR, temp2);
1165                 op2GPR = temp2;
1166             }
1167             
1168             m_jit.move(op1GPR, eax.gpr());
1169             m_jit.assembler().cdq();
1170             m_jit.assembler().idivl_r(op2GPR);
1171             
1172             // Check that there was no remainder. If there had been, then we'd be obligated to
1173             // produce a double result instead.
1174             speculationCheck(m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
1175             
1176             integerResult(eax.gpr(), m_compileIndex);
1177             break;
1178         }
1179         
1180         SpeculateDoubleOperand op1(this, node.child1());
1181         SpeculateDoubleOperand op2(this, node.child2());
1182         FPRTemporary result(this, op1);
1183
1184         FPRReg reg1 = op1.fpr();
1185         FPRReg reg2 = op2.fpr();
1186         m_jit.divDouble(reg1, reg2, result.fpr());
1187
1188         doubleResult(result.fpr(), m_compileIndex);
1189         break;
1190     }
1191
1192     case ArithMod: {
1193         if (shouldNotSpeculateInteger(node.child1()) || shouldNotSpeculateInteger(node.child2())
1194             || !nodeCanSpeculateInteger(node.arithNodeFlags())) {
1195             SpeculateDoubleOperand op1(this, node.child1());
1196             SpeculateDoubleOperand op2(this, node.child2());
1197             
1198             FPRReg op1FPR = op1.fpr();
1199             FPRReg op2FPR = op2.fpr();
1200             
1201             flushRegisters();
1202             
1203             FPRResult result(this);
1204
1205             callOperation(fmod, result.fpr(), op1FPR, op2FPR);
1206             
1207             doubleResult(result.fpr(), m_compileIndex);
1208             break;
1209         }
1210         
1211         SpeculateIntegerOperand op1(this, node.child1());
1212         SpeculateIntegerOperand op2(this, node.child2());
1213         GPRTemporary eax(this, X86Registers::eax);
1214         GPRTemporary edx(this, X86Registers::edx);
1215         GPRReg op1Gpr = op1.gpr();
1216         GPRReg op2Gpr = op2.gpr();
1217
1218         speculationCheck(m_jit.branchTest32(JITCompiler::Zero, op2Gpr));
1219
1220         GPRReg temp2 = InvalidGPRReg;
1221         if (op2Gpr == X86Registers::eax || op2Gpr == X86Registers::edx) {
1222             temp2 = allocate();
1223             m_jit.move(op2Gpr, temp2);
1224             op2Gpr = temp2;
1225         }
1226
1227         m_jit.move(op1Gpr, eax.gpr());
1228         m_jit.assembler().cdq();
1229         m_jit.assembler().idivl_r(op2Gpr);
1230
1231         if (temp2 != InvalidGPRReg)
1232             unlock(temp2);
1233
1234         integerResult(edx.gpr(), m_compileIndex);
1235         break;
1236     }
1237         
1238     case ArithAbs: {
1239         if (shouldSpeculateInteger(node.child1()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1240             SpeculateIntegerOperand op1(this, node.child1());
1241             GPRTemporary result(this, op1);
1242             GPRTemporary scratch(this);
1243             
1244             m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
1245             m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
1246             m_jit.add32(scratch.gpr(), result.gpr());
1247             m_jit.xor32(scratch.gpr(), result.gpr());
1248             speculationCheck(m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
1249             integerResult(result.gpr(), m_compileIndex);
1250             break;
1251         }
1252         
1253         SpeculateDoubleOperand op1(this, node.child1());
1254         FPRTemporary result(this);
1255         
1256         static const double negativeZeroConstant = -0.0;
1257         
1258         m_jit.loadDouble(&negativeZeroConstant, result.fpr());
1259         m_jit.andnotDouble(op1.fpr(), result.fpr());
1260         doubleResult(result.fpr(), m_compileIndex);
1261         break;
1262     }
1263         
1264     case ArithMin:
1265     case ArithMax: {
1266         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1267             SpeculateStrictInt32Operand op1(this, node.child1());
1268             SpeculateStrictInt32Operand op2(this, node.child2());
1269             GPRTemporary result(this, op1);
1270             
1271             MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
1272             m_jit.move(op2.gpr(), result.gpr());
1273             if (op1.gpr() != result.gpr()) {
1274                 MacroAssembler::Jump done = m_jit.jump();
1275                 op1Less.link(&m_jit);
1276                 m_jit.move(op1.gpr(), result.gpr());
1277                 done.link(&m_jit);
1278             } else
1279                 op1Less.link(&m_jit);
1280             
1281             integerResult(result.gpr(), m_compileIndex);
1282             break;
1283         }
1284         
1285         SpeculateDoubleOperand op1(this, node.child1());
1286         SpeculateDoubleOperand op2(this, node.child2());
1287         FPRTemporary result(this, op1);
1288         
1289         MacroAssembler::JumpList done;
1290         
1291         MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
1292         
1293         // op2 is eather the lesser one or one of then is NaN
1294         MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThan : MacroAssembler::DoubleLessThan, op1.fpr(), op2.fpr());
1295         
1296         // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 
1297         // op1 + op2 and putting it into result.
1298         m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
1299         done.append(m_jit.jump());
1300         
1301         op2Less.link(&m_jit);
1302         m_jit.moveDouble(op2.fpr(), result.fpr());
1303         
1304         if (op1.fpr() != result.fpr()) {
1305             done.append(m_jit.jump());
1306             
1307             op1Less.link(&m_jit);
1308             m_jit.moveDouble(op1.fpr(), result.fpr());
1309         } else
1310             op1Less.link(&m_jit);
1311         
1312         done.link(&m_jit);
1313         
1314         doubleResult(result.fpr(), m_compileIndex);
1315         break;
1316     }
1317         
1318     case ArithSqrt: {
1319         SpeculateDoubleOperand op1(this, node.child1());
1320         FPRTemporary result(this, op1);
1321         
1322         m_jit.sqrtDouble(op1.fpr(), result.fpr());
1323         
1324         doubleResult(result.fpr(), m_compileIndex);
1325         break;
1326     }
1327
1328     case LogicalNot: {
1329         if (isKnownBoolean(node.child1())) {
1330             SpeculateBooleanOperand value(this, node.child1());
1331             GPRTemporary result(this, value);
1332             
1333             m_jit.move(value.gpr(), result.gpr());
1334             m_jit.xorPtr(TrustedImm32(true), result.gpr());
1335             
1336             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1337             break;
1338         }
1339         
1340         PredictedType prediction = m_jit.getPrediction(node.child1());
1341         if (isBooleanPrediction(prediction) || !prediction) {
1342             JSValueOperand value(this, node.child1());
1343             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
1344             
1345             m_jit.move(value.gpr(), result.gpr());
1346             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1347             speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1348             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
1349             
1350             // If we add a DataFormatBool, we should use it here.
1351             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1352             break;
1353         }
1354         
1355         nonSpeculativeLogicalNot(node);
1356         
1357         break;
1358     }
1359
1360     case CompareLess:
1361         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
1362             return;
1363         break;
1364
1365     case CompareLessEq:
1366         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
1367             return;
1368         break;
1369
1370     case CompareGreater:
1371         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
1372             return;
1373         break;
1374
1375     case CompareGreaterEq:
1376         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
1377             return;
1378         break;
1379
1380     case CompareEq:
1381         if (isNullConstant(node.child1())) {
1382             if (nonSpeculativeCompareNull(node, node.child2()))
1383                 return;
1384             break;
1385         }
1386         if (isNullConstant(node.child2())) {
1387             if (nonSpeculativeCompareNull(node, node.child1()))
1388                 return;
1389             break;
1390         }
1391         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
1392             return;
1393         break;
1394
1395     case CompareStrictEq:
1396         if (nonSpeculativeStrictEq(node))
1397             return;
1398         break;
1399
1400     case GetByVal: {
1401         ASSERT(node.child3() == NoNode);
1402         SpeculateCellOperand base(this, node.child1());
1403         SpeculateStrictInt32Operand property(this, node.child2());
1404         GPRTemporary storage(this);
1405
1406         GPRReg baseReg = base.gpr();
1407         GPRReg propertyReg = property.gpr();
1408         GPRReg storageReg = storage.gpr();
1409         
1410         if (!m_compileOkay)
1411             return;
1412
1413         // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
1414         // an access with offset JSArray::storageOffset() is valid for all JSCells!
1415         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1416
1417         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1418         // If we have predicted the base to be type array, we can skip the check.
1419         if (!isKnownArray(node.child1()))
1420             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1421         speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
1422
1423         // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
1424         // the storage pointer - especially if there happens to be another register free right now. If we do so,
1425         // then we'll need to allocate a new temporary for result.
1426         GPRTemporary& result = storage;
1427         m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
1428         speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
1429
1430         jsValueResult(result.gpr(), m_compileIndex);
1431         break;
1432     }
1433
1434     case PutByVal: {
1435         SpeculateCellOperand base(this, node.child1());
1436         SpeculateStrictInt32Operand property(this, node.child2());
1437         JSValueOperand value(this, node.child3());
1438         GPRTemporary scratch(this);
1439
1440         // Map base, property & value into registers, allocate a scratch register.
1441         GPRReg baseReg = base.gpr();
1442         GPRReg propertyReg = property.gpr();
1443         GPRReg valueReg = value.gpr();
1444         GPRReg scratchReg = scratch.gpr();
1445         
1446         if (!m_compileOkay)
1447             return;
1448
1449         writeBarrier(baseReg, value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg);
1450
1451         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1452         // If we have predicted the base to be type array, we can skip the check.
1453         if (!isKnownArray(node.child1()))
1454             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1455
1456         base.use();
1457         property.use();
1458         value.use();
1459         
1460         MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
1461
1462         // Code to handle put beyond array bounds.
1463         silentSpillAllRegisters(scratchReg);
1464         setupStubArguments(baseReg, propertyReg, valueReg);
1465         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1466         JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationPutByValBeyondArrayBounds);
1467         silentFillAllRegisters(scratchReg);
1468         JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
1469
1470         withinArrayBounds.link(&m_jit);
1471
1472         // Get the array storage.
1473         GPRReg storageReg = scratchReg;
1474         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1475
1476         // Check if we're writing to a hole; if so increment m_numValuesInVector.
1477         MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1478         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
1479
1480         // If we're writing to a hole we might be growing the array; 
1481         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1482         m_jit.add32(TrustedImm32(1), propertyReg);
1483         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1484         m_jit.sub32(TrustedImm32(1), propertyReg);
1485
1486         lengthDoesNotNeedUpdate.link(&m_jit);
1487         notHoleValue.link(&m_jit);
1488
1489         // Store the value to the array.
1490         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1491
1492         wasBeyondArrayBounds.link(&m_jit);
1493
1494         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1495         break;
1496     }
1497
1498     case PutByValAlias: {
1499         SpeculateCellOperand base(this, node.child1());
1500         SpeculateStrictInt32Operand property(this, node.child2());
1501         JSValueOperand value(this, node.child3());
1502         GPRTemporary scratch(this);
1503         
1504         GPRReg baseReg = base.gpr();
1505         GPRReg scratchReg = scratch.gpr();
1506
1507         writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg);
1508
1509         // Get the array storage.
1510         GPRReg storageReg = scratchReg;
1511         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1512
1513         // Store the value to the array.
1514         GPRReg propertyReg = property.gpr();
1515         GPRReg valueReg = value.gpr();
1516         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1517
1518         noResult(m_compileIndex);
1519         break;
1520     }
1521
1522     case DFG::Jump: {
1523         BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1524         if (taken != (m_block + 1))
1525             addBranch(m_jit.jump(), taken);
1526         noResult(m_compileIndex);
1527         break;
1528     }
1529
1530     case Branch:
1531         if (isStrictInt32(node.child1())) {
1532             SpeculateStrictInt32Operand op(this, node.child1());
1533             
1534             BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1535             BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
1536             
1537             MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1538             
1539             if (taken == (m_block + 1)) {
1540                 condition = MacroAssembler::Zero;
1541                 BlockIndex tmp = taken;
1542                 taken = notTaken;
1543                 notTaken = tmp;
1544             }
1545             
1546             addBranch(m_jit.branchTest32(condition, op.gpr()), taken);
1547             if (notTaken != (m_block + 1))
1548                 addBranch(m_jit.jump(), notTaken);
1549             
1550             noResult(m_compileIndex);
1551             break;
1552         }
1553         if (shouldSpeculateInteger(node.child1())) {
1554             SpeculateIntegerOperand op(this, node.child1());
1555
1556             BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1557             BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
1558             
1559             MacroAssembler::RelationalCondition condition = MacroAssembler::NotEqual;
1560
1561             if (taken == (m_block + 1)) {
1562                 condition = MacroAssembler::Equal;
1563                 BlockIndex tmp = taken;
1564                 taken = notTaken;
1565                 notTaken = tmp;
1566             }
1567             
1568             addBranch(m_jit.branchPtr(condition, op.gpr(), GPRInfo::tagTypeNumberRegister), taken);
1569
1570             if (notTaken != (m_block + 1))
1571                 addBranch(m_jit.jump(), notTaken);
1572             
1573             noResult(m_compileIndex);
1574             break;
1575         }
1576         emitBranch(node);
1577         break;
1578
1579     case Return: {
1580         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
1581         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
1582         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
1583
1584 #if ENABLE(DFG_SUCCESS_STATS)
1585         static SamplingCounter counter("SpeculativeJIT");
1586         m_jit.emitCount(counter);
1587 #endif
1588
1589         // Return the result in returnValueGPR.
1590         JSValueOperand op1(this, node.child1());
1591         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
1592
1593         // Grab the return address.
1594         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT1);
1595         // Restore our caller's "r".
1596         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister);
1597         // Return.
1598         m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT1);
1599         m_jit.ret();
1600         
1601         noResult(m_compileIndex);
1602         break;
1603     }
1604         
1605     case Throw:
1606     case ThrowReferenceError: {
1607         // We expect that throw statements are rare and are intended to exit the code block
1608         // anyway, so we just OSR back to the old JIT for now.
1609         terminateSpeculativeExecution();
1610         break;
1611     }
1612         
1613     case ToPrimitive: {
1614         if (shouldSpeculateInteger(node.child1())) {
1615             // It's really profitable to speculate integer, since it's really cheap,
1616             // it means we don't have to do any real work, and we emit a lot less code.
1617             
1618             SpeculateIntegerOperand op1(this, node.child1());
1619             GPRTemporary result(this, op1);
1620             
1621             m_jit.move(op1.gpr(), result.gpr());
1622             if (op1.format() == DataFormatInteger)
1623                 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, result.gpr());
1624             
1625             jsValueResult(result.gpr(), m_compileIndex);
1626             break;
1627         }
1628         
1629         // FIXME: Add string speculation here.
1630         
1631         bool wasPrimitive = isKnownNumeric(node.child1()) || isKnownBoolean(node.child1());
1632         
1633         JSValueOperand op1(this, node.child1());
1634         GPRTemporary result(this, op1);
1635         
1636         GPRReg op1GPR = op1.gpr();
1637         GPRReg resultGPR = result.gpr();
1638         
1639         op1.use();
1640         
1641         if (wasPrimitive)
1642             m_jit.move(op1GPR, resultGPR);
1643         else {
1644             MacroAssembler::JumpList alreadyPrimitive;
1645             
1646             alreadyPrimitive.append(m_jit.branchTestPtr(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister));
1647             alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1648             
1649             silentSpillAllRegisters(resultGPR);
1650             m_jit.move(op1GPR, GPRInfo::argumentGPR1);
1651             m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1652             appendCallWithExceptionCheck(operationToPrimitive);
1653             m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1654             silentFillAllRegisters(resultGPR);
1655             
1656             MacroAssembler::Jump done = m_jit.jump();
1657             
1658             alreadyPrimitive.link(&m_jit);
1659             m_jit.move(op1GPR, resultGPR);
1660             
1661             done.link(&m_jit);
1662         }
1663         
1664         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1665         break;
1666     }
1667         
1668     case StrCat:
1669     case NewArray: {
1670         // We really don't want to grow the register file just to do a StrCat or NewArray.
1671         // Say we have 50 functions on the stack that all have a StrCat in them that has
1672         // upwards of 10 operands. In the DFG this would mean that each one gets
1673         // some random virtual register, and then to do the StrCat we'd need a second
1674         // span of 10 operands just to have somewhere to copy the 10 operands to, where
1675         // they'd be contiguous and we could easily tell the C code how to find them.
1676         // Ugly! So instead we use the scratchBuffer infrastructure in JSGlobalData. That
1677         // way, those 50 functions will share the same scratchBuffer for offloading their
1678         // StrCat operands. It's about as good as we can do, unless we start doing
1679         // virtual register coalescing to ensure that operands to StrCat get spilled
1680         // in exactly the place where StrCat wants them, or else have the StrCat
1681         // refer to those operands' SetLocal instructions to force them to spill in
1682         // the right place. Basically, any way you cut it, the current approach
1683         // probably has the best balance of performance and sensibility in the sense
1684         // that it does not increase the complexity of the DFG JIT just to make StrCat
1685         // fast and pretty.
1686         
1687         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_jit.globalData()->scratchBufferForSize(sizeof(EncodedJSValue) * node.numChildren()));
1688         
1689         for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
1690             JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
1691             GPRReg opGPR = operand.gpr();
1692             operand.use();
1693             
1694             m_jit.storePtr(opGPR, buffer + operandIdx);
1695         }
1696         
1697         flushRegisters();
1698         
1699         GPRResult result(this);
1700         
1701         callOperation(op == StrCat ? operationStrCat : operationNewArray, result.gpr(), buffer, node.numChildren());
1702         
1703         cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
1704         break;
1705     }
1706         
1707     case NewArrayBuffer: {
1708         flushRegisters();
1709         GPRResult result(this);
1710         
1711         callOperation(operationNewArrayBuffer, result.gpr(), node.startConstant(), node.numConstants());
1712         
1713         cellResult(result.gpr(), m_compileIndex);
1714         break;
1715     }
1716         
1717     case NewRegexp: {
1718         flushRegisters();
1719         GPRResult result(this);
1720         
1721         callOperation(operationNewRegexp, result.gpr(), m_jit.codeBlock()->regexp(node.regexpIndex()));
1722         
1723         cellResult(result.gpr(), m_compileIndex);
1724         break;
1725     }
1726         
1727     case ConvertThis: {
1728         SpeculateCellOperand thisValue(this, node.child1());
1729
1730         speculationCheck(m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValue.gpr()), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1731
1732         cellResult(thisValue.gpr(), m_compileIndex);
1733         break;
1734     }
1735         
1736     case CreateThis: {
1737         // Note that there is not so much profit to speculate here. The only things we
1738         // speculate on are (1) that it's a cell, since that eliminates cell checks
1739         // later if the proto is reused, and (2) if we have a FinalObject prediction
1740         // then we speculate because we want to get recompiled if it isn't (since
1741         // otherwise we'd start taking slow path a lot).
1742         
1743         SpeculateCellOperand proto(this, node.child1());
1744         GPRTemporary result(this);
1745         GPRTemporary scratch(this);
1746         
1747         GPRReg protoGPR = proto.gpr();
1748         GPRReg resultGPR = result.gpr();
1749         GPRReg scratchGPR = scratch.gpr();
1750         
1751         proto.use();
1752         
1753         MacroAssembler::JumpList slowPath;
1754         
1755         // Need to verify that the prototype is an object. If we have reason to believe
1756         // that it's a FinalObject then we speculate on that directly. Otherwise we
1757         // do the slow (structure-based) check.
1758         if (shouldSpeculateFinalObject(node.child1()))
1759             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));
1760         else {
1761             m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);
1762             slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
1763         }
1764         
1765         // Load the inheritorID (the Structure that objects who have protoGPR as the prototype
1766         // use to refer to that prototype). If the inheritorID is not set, go to slow path.
1767         m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSObject::offsetOfInheritorID()), scratchGPR);
1768         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, scratchGPR));
1769         
1770         emitAllocateJSFinalObject(scratchGPR, resultGPR, scratchGPR, slowPath);
1771         
1772         MacroAssembler::Jump done = m_jit.jump();
1773         
1774         slowPath.link(&m_jit);
1775         
1776         silentSpillAllRegisters(resultGPR);
1777         m_jit.move(protoGPR, GPRInfo::argumentGPR1);
1778         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1779         appendCallWithExceptionCheck(operationCreateThis);
1780         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1781         silentFillAllRegisters(resultGPR);
1782         
1783         done.link(&m_jit);
1784         
1785         cellResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1786         break;
1787     }
1788         
1789     case NewObject: {
1790         GPRTemporary result(this);
1791         GPRTemporary scratch(this);
1792         
1793         GPRReg resultGPR = result.gpr();
1794         GPRReg scratchGPR = scratch.gpr();
1795         
1796         MacroAssembler::JumpList slowPath;
1797         
1798         emitAllocateJSFinalObject(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()->emptyObjectStructure()), resultGPR, scratchGPR, slowPath);
1799         
1800         MacroAssembler::Jump done = m_jit.jump();
1801         
1802         slowPath.link(&m_jit);
1803         
1804         silentSpillAllRegisters(resultGPR);
1805         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1806         appendCallWithExceptionCheck(operationNewObject);
1807         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1808         silentFillAllRegisters(resultGPR);
1809         
1810         done.link(&m_jit);
1811         
1812         cellResult(resultGPR, m_compileIndex);
1813         break;
1814     }
1815         
1816     case GetCallee: {
1817         GPRTemporary result(this);
1818         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::Callee)), result.gpr());
1819         cellResult(result.gpr(), m_compileIndex);
1820         break;
1821     }
1822
1823     case GetScopeChain: {
1824         GPRTemporary result(this);
1825         GPRReg resultGPR = result.gpr();
1826
1827         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR);
1828         bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
1829         int skip = node.scopeChainDepth();
1830         ASSERT(skip || !checkTopLevel);
1831         if (checkTopLevel && skip--) {
1832             JITCompiler::Jump activationNotCreated;
1833             if (checkTopLevel)
1834                 activationNotCreated = m_jit.branchTestPtr(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
1835             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
1836             activationNotCreated.link(&m_jit);
1837         }
1838         while (skip--)
1839             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
1840         
1841         m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, object)), resultGPR);
1842
1843         cellResult(resultGPR, m_compileIndex);
1844         break;
1845     }
1846     case GetScopedVar: {
1847         SpeculateCellOperand scopeChain(this, node.child1());
1848         GPRTemporary result(this);
1849         GPRReg resultGPR = result.gpr();
1850         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), resultGPR);
1851         m_jit.loadPtr(JITCompiler::Address(resultGPR, node.varNumber() * sizeof(Register)), resultGPR);
1852         jsValueResult(resultGPR, m_compileIndex);
1853         break;
1854     }
1855     case PutScopedVar: {
1856         SpeculateCellOperand scopeChain(this, node.child1());
1857         GPRTemporary scratchRegister(this);
1858         GPRReg scratchGPR = scratchRegister.gpr();
1859         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), scratchGPR);
1860         JSValueOperand value(this, node.child2());
1861         m_jit.storePtr(value.gpr(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register)));
1862         writeBarrier(scopeChain.gpr(), value.gpr(), node.child2(), WriteBarrierForVariableAccess, scratchGPR);
1863         noResult(m_compileIndex);
1864         break;
1865     }
1866     case GetById: {
1867         SpeculateCellOperand base(this, node.child1());
1868         GPRTemporary result(this, base);
1869         
1870         GPRReg baseGPR = base.gpr();
1871         GPRReg resultGPR = result.gpr();
1872         GPRReg scratchGPR;
1873         
1874         if (resultGPR == baseGPR)
1875             scratchGPR = tryAllocate();
1876         else
1877             scratchGPR = resultGPR;
1878         
1879         base.use();
1880
1881         cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
1882
1883         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1884         break;
1885     }
1886         
1887     case GetArrayLength: {
1888         SpeculateCellOperand base(this, node.child1());
1889         GPRTemporary result(this);
1890         
1891         GPRReg baseGPR = base.gpr();
1892         GPRReg resultGPR = result.gpr();
1893         
1894         if (!isKnownArray(node.child1()))
1895             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1896         
1897         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
1898         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
1899         
1900         speculationCheck(m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
1901         
1902         integerResult(resultGPR, m_compileIndex);
1903         break;
1904     }
1905
1906     case CheckStructure: {
1907         SpeculateCellOperand base(this, node.child1());
1908         GPRTemporary result(this, base);
1909         
1910         GPRReg baseGPR = base.gpr();
1911         GPRReg resultGPR = result.gpr();
1912         
1913         speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structure())));
1914         
1915         m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
1916         
1917         storageResult(resultGPR, m_compileIndex);
1918         break;
1919     }
1920         
1921     case GetByOffset: {
1922         StorageOperand storage(this, node.child1());
1923         GPRTemporary result(this, storage);
1924         
1925         GPRReg storageGPR = storage.gpr();
1926         GPRReg resultGPR = result.gpr();
1927         
1928         StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
1929         
1930         m_jit.loadPtr(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue)), resultGPR);
1931         
1932         jsValueResult(resultGPR, m_compileIndex);
1933         break;
1934     }
1935         
1936     case GetMethod: {
1937         SpeculateCellOperand base(this, node.child1());
1938         GPRTemporary result(this, base);
1939
1940         GPRReg baseGPR = base.gpr();
1941         GPRReg resultGPR = result.gpr();
1942         GPRReg scratchGPR;
1943         
1944         if (resultGPR == baseGPR)
1945             scratchGPR = tryAllocate();
1946         else
1947             scratchGPR = resultGPR;
1948         
1949         base.use();
1950
1951         cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
1952
1953         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1954         break;
1955     }
1956         
1957     case CheckMethod: {
1958         MethodCheckData& methodCheckData = m_jit.graph().m_methodCheckData[node.methodCheckDataIndex()];
1959         
1960         SpeculateCellOperand base(this, node.child1());
1961         GPRTemporary scratch(this); // this needs to be a separate register, unfortunately.
1962         GPRReg baseGPR = base.gpr();
1963         GPRReg scratchGPR = scratch.gpr();
1964         
1965         speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure)));
1966         if (methodCheckData.prototype != m_jit.codeBlock()->globalObject()->methodCallDummy()) {
1967             m_jit.move(JITCompiler::TrustedImmPtr(methodCheckData.prototype->structureAddress()), scratchGPR);
1968             speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure)));
1969         }
1970         
1971         useChildren(node);
1972         initConstantInfo(m_compileIndex);
1973         break;
1974     }
1975
1976     case PutById: {
1977         SpeculateCellOperand base(this, node.child1());
1978         JSValueOperand value(this, node.child2());
1979         GPRTemporary scratch(this);
1980         
1981         GPRReg baseGPR = base.gpr();
1982         GPRReg valueGPR = value.gpr();
1983         GPRReg scratchGPR = scratch.gpr();
1984         
1985         base.use();
1986         value.use();
1987
1988         cachedPutById(baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), NotDirect);
1989         
1990         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1991         break;
1992     }
1993
1994     case PutByIdDirect: {
1995         SpeculateCellOperand base(this, node.child1());
1996         JSValueOperand value(this, node.child2());
1997         GPRTemporary scratch(this);
1998         
1999         GPRReg baseGPR = base.gpr();
2000         GPRReg valueGPR = value.gpr();
2001         GPRReg scratchGPR = scratch.gpr();
2002         
2003         base.use();
2004         value.use();
2005
2006         cachedPutById(baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), Direct);
2007
2008         noResult(m_compileIndex, UseChildrenCalledExplicitly);
2009         break;
2010     }
2011
2012     case GetGlobalVar: {
2013         GPRTemporary result(this);
2014
2015         JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
2016         m_jit.loadPtr(globalObject->addressOfRegisters(), result.gpr());
2017         m_jit.loadPtr(JITCompiler::addressForGlobalVar(result.gpr(), node.varNumber()), result.gpr());
2018
2019         jsValueResult(result.gpr(), m_compileIndex);
2020         break;
2021     }
2022
2023     case PutGlobalVar: {
2024         JSValueOperand value(this, node.child1());
2025         GPRTemporary globalObject(this);
2026         GPRTemporary scratch(this);
2027         
2028         GPRReg globalObjectReg = globalObject.gpr();
2029         GPRReg scratchReg = scratch.gpr();
2030
2031         m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectReg);
2032
2033         writeBarrier(m_jit.codeBlock()->globalObject(), value.gpr(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
2034
2035         m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
2036         m_jit.storePtr(value.gpr(), JITCompiler::addressForGlobalVar(scratchReg, node.varNumber()));
2037
2038         noResult(m_compileIndex);
2039         break;
2040     }
2041
2042     case CheckHasInstance: {
2043         SpeculateCellOperand base(this, node.child1());
2044         GPRTemporary structure(this);
2045
2046         // Speculate that base 'ImplementsDefaultHasInstance'.
2047         m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
2048         speculationCheck(m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
2049
2050         noResult(m_compileIndex);
2051         break;
2052     }
2053
2054     case InstanceOf: {
2055         SpeculateCellOperand value(this, node.child1());
2056         // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
2057         SpeculateCellOperand prototype(this, node.child3());
2058
2059         GPRTemporary scratch(this);
2060
2061         GPRReg valueReg = value.gpr();
2062         GPRReg prototypeReg = prototype.gpr();
2063         GPRReg scratchReg = scratch.gpr();
2064
2065         // Check that prototype is an object.
2066         m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
2067         speculationCheck(m_jit.branchIfNotObject(scratchReg));
2068
2069         // Initialize scratchReg with the value being checked.
2070         m_jit.move(valueReg, scratchReg);
2071
2072         // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
2073         MacroAssembler::Label loop(&m_jit);
2074         m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
2075         m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
2076         MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
2077         m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
2078
2079         // No match - result is false.
2080         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
2081         MacroAssembler::Jump putResult = m_jit.jump();
2082
2083         isInstance.link(&m_jit);
2084         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
2085
2086         putResult.link(&m_jit);
2087         jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
2088         break;
2089     }
2090
2091     case Phi:
2092         ASSERT_NOT_REACHED();
2093
2094     case Breakpoint:
2095 #if ENABLE(DEBUG_WITH_BREAKPOINT)
2096         m_jit.breakpoint();
2097 #else
2098         ASSERT_NOT_REACHED();
2099 #endif
2100         break;
2101         
2102     case Call:
2103     case Construct:
2104         emitCall(node);
2105         break;
2106
2107     case Resolve: {
2108         flushRegisters();
2109         GPRResult result(this);
2110         callOperation(operationResolve, result.gpr(), identifier(node.identifierNumber()));
2111         jsValueResult(result.gpr(), m_compileIndex);
2112         break;
2113     }
2114
2115     case ResolveBase: {
2116         flushRegisters();
2117         GPRResult result(this);
2118         callOperation(operationResolveBase, result.gpr(), identifier(node.identifierNumber()));
2119         jsValueResult(result.gpr(), m_compileIndex);
2120         break;
2121     }
2122
2123     case ResolveBaseStrictPut: {
2124         flushRegisters();
2125         GPRResult result(this);
2126         callOperation(operationResolveBaseStrictPut, result.gpr(), identifier(node.identifierNumber()));
2127         jsValueResult(result.gpr(), m_compileIndex);
2128         break;
2129     }
2130
2131     case ResolveGlobal: {
2132         GPRTemporary globalObject(this);
2133         GPRTemporary resolveInfo(this);
2134         GPRTemporary result(this);
2135
2136         GPRReg globalObjectGPR = globalObject.gpr();
2137         GPRReg resolveInfoGPR = resolveInfo.gpr();
2138         GPRReg resultGPR = result.gpr();
2139
2140         ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
2141         GlobalResolveInfo* resolveInfoAddress = &(m_jit.codeBlock()->globalResolveInfo(data.resolveInfoIndex));
2142
2143         // Check Structure of global object
2144         m_jit.move(JITCompiler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectGPR);
2145         m_jit.move(JITCompiler::TrustedImmPtr(resolveInfoAddress), resolveInfoGPR);
2146         m_jit.loadPtr(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, structure)), resultGPR);
2147         JITCompiler::Jump structuresMatch = m_jit.branchPtr(JITCompiler::Equal, resultGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset()));
2148
2149         silentSpillAllRegisters(resultGPR);
2150         m_jit.move(resolveInfoGPR, GPRInfo::argumentGPR1);
2151         m_jit.move(JITCompiler::TrustedImmPtr(&m_jit.codeBlock()->identifier(data.identifierNumber)), GPRInfo::argumentGPR2);
2152         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
2153         JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationResolveGlobal);
2154         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
2155         silentFillAllRegisters(resultGPR);
2156
2157         JITCompiler::Jump wasSlow = m_jit.jump();
2158
2159         // Fast case
2160         structuresMatch.link(&m_jit);
2161         m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
2162         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
2163         m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr), resultGPR);
2164
2165         wasSlow.link(&m_jit);
2166
2167         jsValueResult(resultGPR, m_compileIndex);
2168         break;
2169     }
2170
2171     case ForceOSRExit: {
2172         terminateSpeculativeExecution();
2173         break;
2174     }
2175
2176     case Phantom:
2177         // This is a no-op.
2178         noResult(m_compileIndex);
2179         break;
2180     }
2181     
2182     if (node.hasResult() && node.mustGenerate())
2183         use(m_compileIndex);
2184 }
2185
2186 void SpeculativeJIT::compileMovHint(Node& node)
2187 {
2188     ASSERT(node.op == SetLocal);
2189     
2190     setNodeIndexForOperand(node.child1(), node.local());
2191     m_lastSetOperand = node.local();
2192 }
2193
2194 void SpeculativeJIT::compile(BasicBlock& block)
2195 {
2196     ASSERT(m_compileOkay);
2197     ASSERT(m_compileIndex == block.begin);
2198     
2199     if (block.isOSRTarget)
2200         m_jit.noticeOSREntry(block);
2201     
2202     m_blockHeads[m_block] = m_jit.label();
2203 #if ENABLE(DFG_JIT_BREAK_ON_EVERY_BLOCK)
2204     m_jit.breakpoint();
2205 #endif
2206     
2207     for (size_t i = 0; i < m_arguments.size(); ++i)
2208         m_arguments[i] = ValueSource();
2209     for (size_t i = 0; i < m_variables.size(); ++i)
2210         m_variables[i] = ValueSource();
2211     m_lastSetOperand = std::numeric_limits<int>::max();
2212     m_bytecodeIndexForOSR = std::numeric_limits<uint32_t>::max();
2213
2214     for (; m_compileIndex < block.end; ++m_compileIndex) {
2215         Node& node = m_jit.graph()[m_compileIndex];
2216         m_bytecodeIndexForOSR = node.codeOrigin.bytecodeIndex();
2217         if (!node.shouldGenerate()) {
2218 #if ENABLE(DFG_DEBUG_VERBOSE)
2219             fprintf(stderr, "SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x     ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex(), m_jit.debugOffset());
2220 #endif
2221             if (node.op == SetLocal)
2222                 compileMovHint(node);
2223         } else {
2224             
2225 #if ENABLE(DFG_DEBUG_VERBOSE)
2226             fprintf(stderr, "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x   ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex(), m_jit.debugOffset());
2227 #endif
2228 #if ENABLE(DFG_JIT_BREAK_ON_EVERY_NODE)
2229             m_jit.breakpoint();
2230 #endif
2231             checkConsistency();
2232             compile(node);
2233             if (!m_compileOkay) {
2234                 m_compileOkay = true;
2235                 m_compileIndex = block.end;
2236                 clearGenerationInfo();
2237                 return;
2238             }
2239             
2240 #if ENABLE(DFG_DEBUG_VERBOSE)
2241             if (node.hasResult()) {
2242                 GenerationInfo& info = m_generationInfo[node.virtualRegister()];
2243                 fprintf(stderr, "-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
2244                 if (info.registerFormat() != DataFormatNone) {
2245                     if (info.registerFormat() == DataFormatDouble)
2246                         fprintf(stderr, ", %s", FPRInfo::debugName(info.fpr()));
2247                     else
2248                         fprintf(stderr, ", %s", GPRInfo::debugName(info.gpr()));
2249                 }
2250                 fprintf(stderr, "    ");
2251             } else
2252                 fprintf(stderr, "    ");
2253 #endif
2254         }
2255         
2256 #if ENABLE(DFG_VERBOSE_VALUE_RECOVERIES)
2257         for (int operand = -m_arguments.size() - RegisterFile::CallFrameHeaderSize; operand < -RegisterFile::CallFrameHeaderSize; ++operand)
2258             computeValueRecoveryFor(operand).dump(stderr);
2259         
2260         fprintf(stderr, " : ");
2261         
2262         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
2263             computeValueRecoveryFor(operand).dump(stderr);
2264 #endif
2265       
2266 #if ENABLE(DFG_DEBUG_VERBOSE)
2267         fprintf(stderr, "\n");
2268 #endif
2269         
2270         if (node.shouldGenerate())
2271             checkConsistency();
2272     }
2273 }
2274
2275 // If we are making type predictions about our arguments then
2276 // we need to check that they are correct on function entry.
2277 void SpeculativeJIT::checkArgumentTypes()
2278 {
2279     ASSERT(!m_compileIndex);
2280     m_bytecodeIndexForOSR = 0;
2281     for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
2282         VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i);
2283         PredictedType predictedType = m_jit.graph().getPrediction(virtualRegister);
2284         if (isInt32Prediction(predictedType))
2285             speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
2286         else if (isArrayPrediction(predictedType)) {
2287             GPRTemporary temp(this);
2288             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
2289             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
2290             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2291         }
2292     }
2293 }
2294
2295 bool SpeculativeJIT::compile()
2296 {
2297     checkArgumentTypes();
2298
2299     ASSERT(!m_compileIndex);
2300     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block)
2301         compile(*m_jit.graph().m_blocks[m_block]);
2302     linkBranches();
2303     return true;
2304 }
2305
2306 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(int operand, const ValueSource& valueSource)
2307 {
2308     if (!valueSource.isSet()) {
2309         if (m_bytecodeIndexForOSR && isInt32Prediction(m_jit.graph().getPrediction(operand)))
2310             return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
2311         return ValueRecovery::alreadyInRegisterFile();
2312     }
2313
2314     if (m_jit.isConstant(valueSource.nodeIndex()))
2315         return ValueRecovery::constant(m_jit.valueOfJSConstant(valueSource.nodeIndex()));
2316     
2317     Node* nodePtr = &m_jit.graph()[valueSource.nodeIndex()];
2318     if (!nodePtr->shouldGenerate()) {
2319         // It's legitimately dead. As in, nobody will ever use this node, or operand,
2320         // ever. Set it to Undefined to make the GC happy after the OSR.
2321         return ValueRecovery::constant(jsUndefined());
2322     }
2323     
2324     GenerationInfo* infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
2325     if (!infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
2326         // Try to see if there is an alternate node that would contain the value we want.
2327         // There are four possibilities:
2328         //
2329         // ValueToNumber: If the only live version of the value is a ValueToNumber node
2330         //    then it means that all remaining uses of the value would have performed a
2331         //    ValueToNumber conversion anyway. Thus, we can substitute ValueToNumber.
2332         //
2333         // ValueToInt32: Likewise, if the only remaining live version of the value is
2334         //    ValueToInt32, then we can use it. But if there is both a ValueToInt32
2335         //    and a ValueToNumber, then we better go with ValueToNumber because it
2336         //    means that some remaining uses would have converted to number while
2337         //    others would have converted to Int32.
2338         //
2339         // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
2340         //    then the only remaining uses are ones that want a properly formed number
2341         //    rather than a UInt32 intermediate.
2342         //
2343         // The reverse of the above: This node could be a UInt32ToNumber, but its
2344         //    alternative is still alive. This means that the only remaining uses of
2345         //    the number would be fine with a UInt32 intermediate.
2346         
2347         bool found = false;
2348         
2349         if (nodePtr->op == UInt32ToNumber) {
2350             NodeIndex nodeIndex = nodePtr->child1();
2351             nodePtr = &m_jit.graph()[nodeIndex];
2352             infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
2353             if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
2354                 found = true;
2355         }
2356         
2357         if (!found) {
2358             NodeIndex valueToNumberIndex = NoNode;
2359             NodeIndex valueToInt32Index = NoNode;
2360             NodeIndex uint32ToNumberIndex = NoNode;
2361             
2362             for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
2363                 GenerationInfo& info = m_generationInfo[virtualRegister];
2364                 if (!info.alive())
2365                     continue;
2366                 if (info.nodeIndex() == NoNode)
2367                     continue;
2368                 Node& node = m_jit.graph()[info.nodeIndex()];
2369                 if (node.child1Unchecked() != valueSource.nodeIndex())
2370                     continue;
2371                 switch (node.op) {
2372                 case ValueToNumber:
2373                 case ValueToDouble:
2374                     valueToNumberIndex = info.nodeIndex();
2375                     break;
2376                 case ValueToInt32:
2377                     valueToInt32Index = info.nodeIndex();
2378                     break;
2379                 case UInt32ToNumber:
2380                     uint32ToNumberIndex = info.nodeIndex();
2381                     break;
2382                 default:
2383                     break;
2384                 }
2385             }
2386             
2387             NodeIndex nodeIndexToUse;
2388             if (valueToNumberIndex != NoNode)
2389                 nodeIndexToUse = valueToNumberIndex;
2390             else if (valueToInt32Index != NoNode)
2391                 nodeIndexToUse = valueToInt32Index;
2392             else if (uint32ToNumberIndex != NoNode)
2393                 nodeIndexToUse = uint32ToNumberIndex;
2394             else
2395                 nodeIndexToUse = NoNode;
2396             
2397             if (nodeIndexToUse != NoNode) {
2398                 nodePtr = &m_jit.graph()[nodeIndexToUse];
2399                 infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
2400                 ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
2401                 found = true;
2402             }
2403         }
2404         
2405         if (!found)
2406             return ValueRecovery::constant(jsUndefined());
2407     }
2408     
2409     ASSERT(infoPtr->alive());
2410
2411     if (infoPtr->registerFormat() != DataFormatNone) {
2412         if (infoPtr->registerFormat() == DataFormatDouble)
2413             return ValueRecovery::inFPR(infoPtr->fpr());
2414         return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
2415     }
2416     if (infoPtr->spillFormat() != DataFormatNone)
2417         return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()));
2418     
2419     ASSERT_NOT_REACHED();
2420     return ValueRecovery();
2421 }
2422
2423 } } // namespace JSC::DFG
2424
2425 #endif
2426 #endif