Chromium Code Reviews| Index: src/x64/codegen-x64.cc |
| diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc |
| index 50e5aa110e7e82ecea528ff8330f2df786ca272c..bf2aa876700d204517c663adc0cda55d8bf1c042 100644 |
| --- a/src/x64/codegen-x64.cc |
| +++ b/src/x64/codegen-x64.cc |
| @@ -7018,7 +7018,43 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, |
| left->reg(), |
| rcx, |
| overwrite_mode); |
| - __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); |
| + |
| + Label do_op; |
| + if (right_type_info.IsSmi()) { |
| + if (FLAG_debug_code) { |
| + __ AbortIfNotSmi(right->reg()); |
| + } |
| + __ movq(answer.reg(), left->reg()); |
| + // If left is not known to be a smi, check if it is. |
| + // If left is not known to be a number, and it isn't a smi, check if |
| + // it is a HeapNumber. |
| + if (!left_type_info.IsSmi()) { |
| + __ JumpIfSmi(answer.reg(), &do_op); |
| + if (!left_type_info.IsNumber()) { |
| + // Branch if not a heapnumber. |
| + __ Cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), |
| + Factory::heap_number_map()); |
| + deferred->Branch(not_equal); |
| + } |
| + // Load integer value into answer register using truncation. |
|
William Hesse
2010/05/21 09:05:27
This is the case we also hope to avoid by using th
|
| + __ cvttsd2si(answer.reg(), |
| + FieldOperand(answer.reg(), HeapNumber::kValueOffset)); |
| + // Branch if we might have overflowed. |
| + // (False negative for Smi::kMinValue) |
| + __ cmpq(answer.reg(), Immediate(0x80000000)); |
| + deferred->Branch(equal); |
| + // TODO(lrn): Inline shifts on int32 here instead of first smi-tagging. |
| + __ Integer32ToSmi(answer.reg(), answer.reg()); |
| + } else { |
| + // Fast case - both are actually smis. |
| + if (FLAG_debug_code) { |
| + __ AbortIfNotSmi(left->reg()); |
| + } |
| + } |
| + } else { |
| + __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); |
| + } |
| + __ bind(&do_op); |
| // Perform the operation. |
| switch (op) { |