| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 5122)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -1201,6 +1201,46 @@
|
| }
|
|
|
|
|
| +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()) {
|
| + Condition is_smi = masm()->CheckSmi(left);
|
| + both_smi->Branch(is_smi);
|
| + } else {
|
| + if (FLAG_debug_code) __ AbortIfNotSmi(left);
|
| + both_smi->Jump();
|
| + }
|
| + } else if (!left_info.IsSmi()) {
|
| + if (!right_info.IsSmi()) {
|
| + Condition is_smi = masm()->CheckBothSmi(left, right);
|
| + both_smi->Branch(is_smi);
|
| + } else {
|
| + Condition is_smi = masm()->CheckSmi(left);
|
| + both_smi->Branch(is_smi);
|
| + }
|
| + } else {
|
| + if (FLAG_debug_code) __ AbortIfNotSmi(left);
|
| + if (!right_info.IsSmi()) {
|
| + Condition is_smi = masm()->CheckSmi(right);
|
| + both_smi->Branch(is_smi);
|
| + } else {
|
| + if (FLAG_debug_code) __ AbortIfNotSmi(right);
|
| + both_smi->Jump();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| void CodeGenerator::JumpIfNotSmiUsingTypeInfo(Register reg,
|
| TypeInfo type,
|
| DeferredCode* deferred) {
|
| @@ -2242,37 +2282,47 @@
|
| Register left_reg = left_side.reg();
|
| Register right_reg = right_side.reg();
|
|
|
| - Condition both_smi = masm_->CheckBothSmi(left_reg, right_reg);
|
| - is_smi.Branch(both_smi);
|
| + // In-line check for comparing two smis.
|
| + 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) {
|
| - __ cmpq(left_side.reg(), 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) {
|
| + __ cmpq(left_side.reg(), 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);
|
| + __ testq(answer.reg(), answer.reg()); // Sets both zero and sign flags.
|
| + 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);
|
| + __ SmiCompare(left_side.reg(), 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);
|
| - __ testq(answer.reg(), answer.reg()); // Sets both zero and sign flags.
|
| - answer.Unuse();
|
| - dest->true_target()->Branch(cc);
|
| - dest->false_target()->Jump();
|
| -
|
| - is_smi.Bind();
|
| - left_side = Result(left_reg);
|
| - right_side = Result(right_reg);
|
| - __ SmiCompare(left_side.reg(), right_side.reg());
|
| - right_side.Unuse();
|
| - left_side.Unuse();
|
| - dest->Split(cc);
|
| }
|
| }
|
| }
|
|
|