Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 8588) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -183,52 +183,96 @@ |
| LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| - LocationSummary* locs = new LocationSummary(2, 0); |
| - locs->set_in(0, Location::RequiresRegister()); |
| - locs->set_in(1, Location::RequiresRegister()); |
| - locs->set_out(Location::RegisterLocation(EAX)); |
| - return locs; |
| + const intptr_t kNumInputs = 2; |
| + if (operands_class_id() == kSmi) { |
| + const intptr_t kNumTemps = 1; |
| + LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + locs->set_in(0, Location::RequiresRegister()); |
| + locs->set_in(1, Location::RequiresRegister()); |
| + locs->set_temp(0, Location::RequiresRegister()); |
| + locs->set_out(Location::RequiresRegister()); |
| + return locs; |
| + } else { |
| + const intptr_t kNumTemps = 0; |
| + LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + locs->set_in(0, Location::RequiresRegister()); |
| + locs->set_in(1, Location::RequiresRegister()); |
| + locs->set_out(Location::RegisterLocation(EAX)); |
| + return locs; |
| + } |
| } |
| void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| - Register left = locs()->in(0).reg(); |
| - Register right = locs()->in(1).reg(); |
| - Register result = locs()->out().reg(); |
| - ASSERT(locs()->out().reg() == EAX); |
| - |
| const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| - const Immediate raw_null = |
| - Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| - Label done, load_true, non_null_compare; |
| - __ cmpl(left, raw_null); |
| - __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| - // Comparison with NULL is "===". |
| - __ cmpl(left, right); |
| - __ j(EQUAL, &load_true, Assembler::kNearJump); |
| - __ LoadObject(result, bool_false); |
| - __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&load_true); |
| - __ LoadObject(result, bool_true); |
| - __ jmp(&done); |
| + if (operands_class_id() == kObject) { |
| + Register left = locs()->in(0).reg(); |
|
Vyacheslav Egorov (Google)
2012/06/13 09:02:27
I think when instruction code is large enough it m
srdjan
2012/06/13 18:34:24
Done.
|
| + Register right = locs()->in(1).reg(); |
| + Register result = locs()->out().reg(); |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + // Inline null comparison. |
| + __ cmpl(left, raw_null); |
| + Label not_null, done, is_true; |
| + __ j(NOT_EQUAL, ¬_null, Assembler::kNearJump); |
| + __ cmpl(left, right); |
| + __ j(EQUAL, &is_true, Assembler::kNearJump); |
| + __ LoadObject(result, bool_false); |
| + __ jmp(&done, Assembler::kNearJump); |
| + __ Bind(&is_true); |
| + __ LoadObject(result, bool_true); |
| + __ jmp(&done, Assembler::kNearJump); |
| - __ Bind(&non_null_compare); |
| - __ pushl(left); |
| - __ pushl(right); |
| - const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); |
| - const int kNumberOfArguments = 2; |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - const int kNumArgumentsChecked = 1; |
| + __ Bind(¬_null); |
| + __ pushl(left); |
| + __ pushl(right); |
| + compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| + cid(), |
| + token_index(), |
| + try_index()); |
| + const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); |
| + const int kNumberOfArguments = 2; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const int kNumArgumentsChecked = 2; |
| - compiler->GenerateInstanceCall(cid(), |
| - token_index(), |
| - try_index(), |
| - operator_name, |
| - kNumberOfArguments, |
| - kNoArgumentNames, |
| - kNumArgumentsChecked); |
| - __ Bind(&done); |
| + compiler->GenerateInstanceCall(cid(), |
| + token_index(), |
| + try_index(), |
| + operator_name, |
| + kNumberOfArguments, |
| + kNoArgumentNames, |
| + kNumArgumentsChecked); |
| + ASSERT(locs()->out().reg() == EAX); |
| + __ Bind(&done); |
| + return; |
| + } |
| + if (operands_class_id() == kSmi) { |
| + // TODO(srdjan): Should we always include NULL test (common case)? |
| + Register left = locs()->in(0).reg(); |
| + Register right = locs()->in(1).reg(); |
| + Register result = locs()->out().reg(); |
| + Register temp = locs()->temp(0).reg(); |
| + Label* deopt = compiler->AddDeoptStub(cid(), |
| + token_index(), |
| + try_index(), |
| + kDeoptSmiCompareSmis, |
| + left, |
| + right); |
| + __ movl(temp, left); |
| + __ orl(temp, right); |
| + __ testl(temp, Immediate(kSmiTagMask)); |
| + __ j(NOT_ZERO, deopt); |
| + __ cmpl(left, right); |
| + Label load_true, done; |
| + __ j(EQUAL, &load_true, Assembler::kNearJump); |
| + __ LoadObject(result, bool_false); |
| + __ jmp(&done, Assembler::kNearJump); |
| + __ Bind(&load_true); |
| + __ LoadObject(result, bool_true); |
| + __ Bind(&done); |
| + return; |
| + } |
| } |
| @@ -1356,7 +1400,6 @@ |
| } |
| } |
| - |
| } // namespace dart |
| #undef __ |