Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 5122) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -1445,6 +1445,51 @@ |
} |
+void CodeGenerator::JumpIfBothSmiUsingTypeInfo(Register left, |
+ Register right, |
+ TypeInfo left_info, |
+ TypeInfo right_info, |
+ JumpTarget* both_smi) { |
+ if (left_info.IsDouble() || left_info.IsString() || |
+ right_info.IsDouble() || right_info.IsString()) { |
+ // We know that left and right are not both smi. Don't do any tests. |
+ return; |
+ } |
+ |
+ if (left.is(right)) { |
+ if (!left_info.IsSmi()) { |
+ __ test(left, Immediate(kSmiTagMask)); |
+ both_smi->Branch(zero); |
+ } else { |
+ if (FLAG_debug_code) __ AbortIfNotSmi(left); |
+ both_smi->Jump(); |
+ } |
+ } else if (!left_info.IsSmi()) { |
+ if (!right_info.IsSmi()) { |
+ Result temp = allocator_->Allocate(); |
+ ASSERT(temp.is_valid()); |
+ __ mov(temp.reg(), left); |
+ __ or_(temp.reg(), Operand(right)); |
+ __ test(temp.reg(), Immediate(kSmiTagMask)); |
+ temp.Unuse(); |
+ both_smi->Branch(zero); |
+ } else { |
+ __ test(left, Immediate(kSmiTagMask)); |
+ both_smi->Branch(zero); |
+ } |
+ } else { |
+ if (FLAG_debug_code) __ AbortIfNotSmi(left); |
+ if (!right_info.IsSmi()) { |
+ __ test(right, Immediate(kSmiTagMask)); |
+ both_smi->Branch(zero); |
+ } else { |
+ if (FLAG_debug_code) __ AbortIfNotSmi(right); |
+ both_smi->Jump(); |
+ } |
+ } |
+} |
+ |
+ |
void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left, |
Register right, |
Register scratch, |
@@ -2735,42 +2780,46 @@ |
Register right_reg = right_side.reg(); |
// In-line check for comparing two smis. |
- Result temp = allocator_->Allocate(); |
- ASSERT(temp.is_valid()); |
- __ mov(temp.reg(), left_side.reg()); |
- __ or_(temp.reg(), Operand(right_side.reg())); |
- __ test(temp.reg(), Immediate(kSmiTagMask)); |
- temp.Unuse(); |
- is_smi.Branch(zero, taken); |
+ JumpIfBothSmiUsingTypeInfo(left_side.reg(), right_side.reg(), |
+ left_side.type_info(), right_side.type_info(), |
+ &is_smi); |
- // Inline the equality check if both operands can't be a NaN. If both |
- // objects are the same they are equal. |
- if (nan_info == kCantBothBeNaN && cc == equal) { |
- __ cmp(left_side.reg(), Operand(right_side.reg())); |
- dest->true_target()->Branch(equal); |
+ if (has_valid_frame()) { |
+ // Inline the equality check if both operands can't be a NaN. If both |
+ // objects are the same they are equal. |
+ if (nan_info == kCantBothBeNaN && cc == equal) { |
+ __ cmp(left_side.reg(), Operand(right_side.reg())); |
+ dest->true_target()->Branch(equal); |
+ } |
+ |
+ // Inlined number comparison: |
+ if (inline_number_compare) { |
+ GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); |
+ } |
+ |
+ // End of in-line compare, call out to the compare stub. Don't include |
+ // number comparison in the stub if it was inlined. |
+ CompareStub stub(cc, strict, nan_info, !inline_number_compare); |
+ Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
+ __ test(answer.reg(), Operand(answer.reg())); |
+ answer.Unuse(); |
+ if (is_smi.is_linked()) { |
+ dest->true_target()->Branch(cc); |
+ dest->false_target()->Jump(); |
+ } else { |
+ dest->Split(cc); |
+ } |
} |
- // Inlined number comparison: |
- if (inline_number_compare) { |
- GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); |
+ if (is_smi.is_linked()) { |
+ is_smi.Bind(); |
+ left_side = Result(left_reg); |
+ right_side = Result(right_reg); |
+ __ cmp(left_side.reg(), Operand(right_side.reg())); |
+ right_side.Unuse(); |
+ left_side.Unuse(); |
+ dest->Split(cc); |
} |
- |
- // End of in-line compare, call out to the compare stub. Don't include |
- // number comparison in the stub if it was inlined. |
- CompareStub stub(cc, strict, nan_info, !inline_number_compare); |
- Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
- __ test(answer.reg(), Operand(answer.reg())); |
- answer.Unuse(); |
- dest->true_target()->Branch(cc); |
- dest->false_target()->Jump(); |
- |
- is_smi.Bind(); |
- left_side = Result(left_reg); |
- right_side = Result(right_reg); |
- __ cmp(left_side.reg(), Operand(right_side.reg())); |
- right_side.Unuse(); |
- left_side.Unuse(); |
- dest->Split(cc); |
} |
} |
} |