Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 10865) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -290,6 +290,35 @@ |
| const Array& kNoArgumentNames = Array::Handle(); |
| const int kNumArgumentsChecked = 2; |
| + Label done, false_label, true_label; |
| + Register left = comp->locs()->in(0).reg(); |
| + Register right = comp->locs()->in(1).reg(); |
| + __ popl(right); |
| + __ popl(left); |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + Label check_identity, instance_call; |
| + __ cmpl(right, raw_null); |
| + __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| + __ cmpl(left, raw_null); |
| + __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); |
| + |
| + __ Bind(&check_identity); |
| + __ cmpl(left, right); |
| + __ j(EQUAL, &true_label); |
| + if (comp->kind() == Token::kEQ) { |
| + __ LoadObject(EAX, compiler->bool_false()); |
| + __ jmp(&done); |
| + __ Bind(&true_label); |
| + __ LoadObject(EAX, compiler->bool_true()); |
| + __ jmp(&done); |
| + } else { |
|
regis
2012/08/17 01:53:45
Code is easier to read if you document this branch
srdjan
2012/08/17 17:26:41
Done.
|
| + __ jmp(&false_label); |
| + } |
| + |
| + __ Bind(&instance_call); |
| + __ pushl(left); |
| + __ pushl(right); |
| compiler->GenerateInstanceCall(comp->deopt_id(), |
| comp->token_pos(), |
| comp->try_index(), |
| @@ -300,15 +329,16 @@ |
| comp->locs()->stack_bitmap()); |
| ASSERT(comp->locs()->out().reg() == EAX); |
| if (comp->kind() == Token::kNE) { |
| - Label done, false_label; |
| + // Negate the condition: true label returns false and vice versa. |
| __ CompareObject(EAX, compiler->bool_true()); |
| - __ j(EQUAL, &false_label, Assembler::kNearJump); |
| + __ j(EQUAL, &true_label, Assembler::kNearJump); |
| + __ Bind(&false_label); |
| __ LoadObject(EAX, compiler->bool_true()); |
| __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&false_label); |
| + __ Bind(&true_label); |
| __ LoadObject(EAX, compiler->bool_false()); |
| - __ Bind(&done); |
| } |
| + __ Bind(&done); |
| } |
| @@ -423,17 +453,25 @@ |
| right); |
| __ testl(left, Immediate(kSmiTagMask)); |
| __ j(ZERO, deopt); |
| + // 'left' is not Smi. |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + Label identity_compare; |
| + __ cmpl(right, raw_null); |
| + __ j(EQUAL, &identity_compare); |
| + __ cmpl(left, raw_null); |
| + __ j(EQUAL, &identity_compare); |
| + |
| __ LoadClassId(temp, left); |
| - Label done; |
| for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| if (i == (ic_data.NumberOfChecks() - 1)) { |
| __ j(NOT_EQUAL, deopt); |
| } else { |
| - __ j(EQUAL, &done); |
| + __ j(EQUAL, &identity_compare); |
| } |
| } |
| - __ Bind(&done); |
| + __ Bind(&identity_compare); |
| __ cmpl(left, right); |
| if (branch == NULL) { |
| Label done, is_equal; |
| @@ -471,10 +509,13 @@ |
| Register right = locs.in(1).reg(); |
| const Immediate raw_null = |
| Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| - Label done, non_null_compare; |
| + Label done, identity_compare, non_null_compare; |
| + __ cmpl(right, raw_null); |
| + __ j(EQUAL, &identity_compare, Assembler::kNearJump); |
| __ cmpl(left, raw_null); |
| __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| // Comparison with NULL is "===". |
| + __ Bind(&identity_compare); |
| __ cmpl(left, right); |
| Condition cond = TokenKindToSmiCondition(kind); |
| if (branch != NULL) { |
| @@ -590,11 +631,13 @@ |
| void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| if (receiver_class_id() == kSmiCid) { |
| + // Deoptimizes if both arguments not Smi. |
| EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. |
| deopt_id(), token_pos(), try_index()); |
| return; |
| } |
| if (receiver_class_id() == kDoubleCid) { |
| + // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
| EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. |
| deopt_id(), token_pos(), try_index()); |
| return; |