Chromium Code Reviews| Index: runtime/vm/intermediate_language_x64.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_x64.cc (revision 10865) |
| +++ runtime/vm/intermediate_language_x64.cc (working copy) |
| @@ -299,6 +299,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(); |
| + __ popq(right); |
| + __ popq(left); |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + Label check_identity, instance_call; |
| + __ cmpq(right, raw_null); |
| + __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| + __ cmpq(left, raw_null); |
| + __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); |
| + |
| + __ Bind(&check_identity); |
| + __ cmpq(left, right); |
| + __ j(EQUAL, &true_label); |
| + if (comp->kind() == Token::kEQ) { |
| + __ LoadObject(RAX, compiler->bool_false()); |
| + __ jmp(&done); |
| + __ Bind(&true_label); |
| + __ LoadObject(RAX, compiler->bool_true()); |
| + __ jmp(&done); |
| + } else { |
|
regis
2012/08/17 01:53:45
ditto
srdjan
2012/08/17 17:26:41
Done.
|
| + __ jmp(&false_label); |
| + } |
| + |
| + __ Bind(&instance_call); |
| + __ pushq(left); |
| + __ pushq(right); |
| compiler->GenerateInstanceCall(comp->deopt_id(), |
| comp->token_pos(), |
| comp->try_index(), |
| @@ -309,15 +338,16 @@ |
| comp->locs()->stack_bitmap()); |
| ASSERT(comp->locs()->out().reg() == RAX); |
| if (comp->kind() == Token::kNE) { |
| - Label done, false_label; |
| + // Negate the condition: true label returns false and vice versa. |
| __ CompareObject(RAX, compiler->bool_true()); |
| - __ j(EQUAL, &false_label, Assembler::kNearJump); |
| + __ j(EQUAL, &true_label, Assembler::kNearJump); |
| + __ Bind(&false_label); |
| __ LoadObject(RAX, compiler->bool_true()); |
| __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&false_label); |
| + __ Bind(&true_label); |
| __ LoadObject(RAX, compiler->bool_false()); |
| - __ Bind(&done); |
| } |
| + __ Bind(&done); |
| } |
| @@ -433,17 +463,25 @@ |
| right); |
| __ testq(left, Immediate(kSmiTagMask)); |
| __ j(ZERO, deopt); |
| + // 'left' is not Smi. |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + Label identity_compare; |
| + __ cmpq(right, raw_null); |
| + __ j(EQUAL, &identity_compare); |
| + __ cmpq(left, raw_null); |
| + __ j(EQUAL, &identity_compare); |
| + |
| __ LoadClassId(temp, left); |
| - Label done; |
| for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| __ cmpq(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); |
| __ cmpq(left, right); |
| if (branch == NULL) { |
| Label done, is_equal; |
| @@ -481,10 +519,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; |
| + __ cmpq(right, raw_null); |
| + __ j(EQUAL, &identity_compare, Assembler::kNearJump); |
| __ cmpq(left, raw_null); |
| __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| // Comparison with NULL is "===". |
| + __ Bind(&identity_compare); |
| __ cmpq(left, right); |
| Condition cond = TokenKindToSmiCondition(kind); |
| if (branch != NULL) { |
| @@ -600,11 +641,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; |