Chromium Code Reviews| Index: src/ia32/codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/codegen-ia32.cc (revision 2154) |
| +++ src/ia32/codegen-ia32.cc (working copy) |
| @@ -1871,13 +1871,19 @@ |
| // Implement comparison against a constant Smi, inlining the case |
| // where both sides are Smis. |
| left_side.ToRegister(); |
| - ASSERT(left_side.is_valid()); |
| + |
| + // Here we split control flow to the stub call and inlined cases |
| + // before finally splitting it to the control destination. We use |
| + // a jump target and branching to duplicate the virtual frame at |
| + // the first split. We manually handle the off-frame references |
| + // by reconstituting them on the non-fall-through path. |
| JumpTarget is_smi; |
| + Register left_reg = left_side.reg(); |
| + Handle<Object> right_val = right_side.handle(); |
| __ test(left_side.reg(), Immediate(kSmiTagMask)); |
| - is_smi.Branch(zero, &left_side, &right_side, taken); |
| + is_smi.Branch(zero, taken); |
| - // Setup and call the compare stub, which expects its arguments |
| - // in registers. |
| + // Setup and call the compare stub. |
| CompareStub stub(cc, strict); |
| Result result = frame_->CallStub(&stub, &left_side, &right_side); |
| result.ToRegister(); |
| @@ -1886,12 +1892,12 @@ |
| dest->true_target()->Branch(cc); |
| dest->false_target()->Jump(); |
| - is_smi.Bind(&left_side, &right_side); |
| - left_side.ToRegister(); |
| + is_smi.Bind(); |
| + left_side = Result(left_reg); |
| + right_side = Result(right_val); |
| // Test smi equality and comparison by signed int comparison. |
| if (IsUnsafeSmi(right_side.handle())) { |
| right_side.ToRegister(); |
| - ASSERT(right_side.is_valid()); |
| __ cmp(left_side.reg(), Operand(right_side.reg())); |
| } else { |
| __ cmp(Operand(left_side.reg()), Immediate(right_side.handle())); |
| @@ -1943,35 +1949,50 @@ |
| (right_side.is_constant() && !right_side.handle()->IsSmi()); |
| left_side.ToRegister(); |
| right_side.ToRegister(); |
| - JumpTarget is_smi; |
| - if (!known_non_smi) { |
| - // Check for the smi case. |
| + |
| + if (known_non_smi) { |
| + // When non-smi, call out to the compare stub. |
| + CompareStub stub(cc, strict); |
| + Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
| + if (cc == equal) { |
| + __ test(answer.reg(), Operand(answer.reg())); |
| + } else { |
| + __ cmp(answer.reg(), 0); |
| + } |
| + answer.Unuse(); |
| + dest->Split(cc); |
| + } else { |
| + // Here we split control flow to the stub call and inlined cases |
| + // before finally splitting it to the control destination. We use |
| + // a jump target and branching to duplicate the virtual frame at |
| + // the first split. We manually handle the off-frame references |
| + // by reconstituting them on the non-fall-through path. |
| + JumpTarget is_smi; |
| + Register left_reg = left_side.reg(); |
| + Register right_reg = right_side.reg(); |
| + |
| 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, &left_side, &right_side, taken); |
| - } |
| - // When non-smi, call out to the compare stub, which expects its |
| - // arguments in registers. |
| - CompareStub stub(cc, strict); |
| - Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
| - if (cc == equal) { |
| - __ test(answer.reg(), Operand(answer.reg())); |
| - } else { |
| - __ cmp(answer.reg(), 0); |
| - } |
| - answer.Unuse(); |
| - if (known_non_smi) { |
| - dest->Split(cc); |
| - } else { |
| + is_smi.Branch(zero, taken); |
| + // When non-smi, call out to the compare stub. |
| + CompareStub stub(cc, strict); |
| + Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
|
William Hesse
2009/06/12 14:05:38
Is it worth a comment that here is where left_side
|
| + if (cc == equal) { |
| + __ test(answer.reg(), Operand(answer.reg())); |
| + } else { |
| + __ cmp(answer.reg(), 0); |
| + } |
| + answer.Unuse(); |
| dest->true_target()->Branch(cc); |
| dest->false_target()->Jump(); |
| - is_smi.Bind(&left_side, &right_side); |
| - left_side.ToRegister(); |
| - right_side.ToRegister(); |
| + |
| + 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(); |