Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1136)

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 27307005: Change == into an instance call to allow polymorphic inlining of ==. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased, addressed comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 29797)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -264,92 +264,11 @@
locs->set_out(Location::RequiresRegister());
return locs;
}
- if (IsCheckedStrictEqual()) {
- const intptr_t kNumTemps = 1;
- LocationSummary* locs =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- 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;
- }
- if (IsPolymorphic()) {
- const intptr_t kNumTemps = 1;
- LocationSummary* locs =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- locs->set_in(0, Location::RegisterLocation(ECX));
- locs->set_in(1, Location::RegisterLocation(EDX));
- locs->set_temp(0, Location::RegisterLocation(EBX));
- locs->set_out(Location::RegisterLocation(EAX));
- return locs;
- }
- const intptr_t kNumTemps = 1;
- LocationSummary* locs =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- locs->set_in(0, Location::RegisterLocation(EBX));
- locs->set_in(1, Location::RegisterLocation(EDX));
- locs->set_temp(0, Location::RegisterLocation(ECX));
- locs->set_out(Location::RegisterLocation(EAX));
- return locs;
+ UNREACHABLE();
+ return NULL;
}
-static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
- intptr_t deopt_id,
- intptr_t token_pos,
- Token::Kind kind,
- LocationSummary* locs,
- const ICData& original_ic_data) {
- if (!compiler->is_optimizing()) {
- compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
- deopt_id,
- token_pos);
- }
- const int kNumberOfArguments = 2;
- const Array& kNoArgumentNames = Object::null_array();
- const int kNumArgumentsChecked = 2;
-
- ICData& equality_ic_data = ICData::ZoneHandle();
- if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
- ASSERT(!original_ic_data.IsNull());
- if (original_ic_data.NumberOfChecks() == 0) {
- // IC call for reoptimization populates original ICData.
- equality_ic_data = original_ic_data.raw();
- } else {
- // Megamorphic call.
- equality_ic_data = original_ic_data.AsUnaryClassChecks();
- }
- } else {
- const Array& arguments_descriptor =
- Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
- kNoArgumentNames));
- equality_ic_data = ICData::New(compiler->parsed_function().function(),
- Symbols::EqualOperator(),
- arguments_descriptor,
- deopt_id,
- kNumArgumentsChecked);
- }
- compiler->GenerateInstanceCall(deopt_id,
- token_pos,
- kNumberOfArguments,
- kNoArgumentNames,
- locs,
- equality_ic_data);
- if (kind == Token::kNE) {
- Label true_label, done;
- // Negate the condition: true label returns false and vice versa.
- __ CompareObject(EAX, Bool::True());
- __ j(EQUAL, &true_label, Assembler::kNearJump);
- __ LoadObject(EAX, Bool::True());
- __ jmp(&done, Assembler::kNearJump);
- __ Bind(&true_label);
- __ LoadObject(EAX, Bool::False());
- __ Bind(&done);
- }
-}
-
-
static void LoadValueCid(FlowGraphCompiler* compiler,
Register value_cid_reg,
Register value_reg,
@@ -369,164 +288,6 @@
}
-static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
- const ICData& orig_ic_data,
- LocationSummary* locs,
- BranchInstr* branch,
- Token::Kind kind,
- intptr_t deopt_id,
- intptr_t token_pos) {
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
- const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
- ASSERT(ic_data.NumberOfChecks() > 0);
- ASSERT(ic_data.num_args_tested() == 1);
- Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
- Register left = locs->in(0).reg();
- Register right = locs->in(1).reg();
- Register temp = locs->temp(0).reg();
- LoadValueCid(compiler, temp, left,
- (ic_data.GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt);
- // 'temp' contains class-id of the left argument.
- ObjectStore* object_store = Isolate::Current()->object_store();
- Condition cond = TokenKindToSmiCondition(kind);
- Label done;
- const intptr_t len = ic_data.NumberOfChecks();
- for (intptr_t i = 0; i < len; i++) {
- // Assert that the Smi is at position 0, if at all.
- ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0));
- Label next_test;
- __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
- if (i < len - 1) {
- __ j(NOT_EQUAL, &next_test);
- } else {
- __ j(NOT_EQUAL, deopt);
- }
- const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
- if (target.Owner() == object_store->object_class()) {
- // Object.== is same as ===.
- __ Drop(2);
- __ cmpl(left, right);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- __ j(cond, &load_true, Assembler::kNearJump);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&load_true);
- __ LoadObject(result, Bool::True());
- }
- } else {
- const int kNumberOfArguments = 2;
- const Array& kNoArgumentNames = Object::null_array();
- compiler->GenerateStaticCall(deopt_id,
- token_pos,
- target,
- kNumberOfArguments,
- kNoArgumentNames,
- locs);
- if (branch == NULL) {
- if (kind == Token::kNE) {
- Label false_label;
- __ CompareObject(EAX, Bool::True());
- __ j(EQUAL, &false_label, Assembler::kNearJump);
- __ LoadObject(EAX, Bool::True());
- __ jmp(&done);
- __ Bind(&false_label);
- __ LoadObject(EAX, Bool::False());
- }
- } else {
- if (branch->is_checked()) {
- EmitAssertBoolean(EAX, token_pos, deopt_id, locs, compiler);
- }
- __ CompareObject(EAX, Bool::True());
- branch->EmitBranchOnCondition(compiler, cond);
- }
- }
- if (i < len - 1) {
- __ jmp(&done);
- __ Bind(&next_test);
- }
- }
- __ Bind(&done);
-}
-
-
-// Emit code when ICData's targets are all Object == (which is ===).
-static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
- const ICData& orig_ic_data,
- const LocationSummary& locs,
- Token::Kind kind,
- BranchInstr* branch,
- intptr_t deopt_id) {
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
- Register left = locs.in(0).reg();
- Register right = locs.in(1).reg();
- Register temp = locs.temp(0).reg();
- Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
- __ 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);
- const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
- const intptr_t len = ic_data.NumberOfChecks();
- for (intptr_t i = 0; i < len; i++) {
- __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
- if (i == (len - 1)) {
- __ j(NOT_EQUAL, deopt);
- } else {
- __ j(EQUAL, &identity_compare);
- }
- }
- __ Bind(&identity_compare);
- __ cmpl(left, right);
- if (branch == NULL) {
- Label done, is_equal;
- Register result = locs.out().reg();
- __ j(EQUAL, &is_equal, Assembler::kNearJump);
- // Not equal.
- __ LoadObject(result, Bool::Get(kind != Token::kEQ));
- __ jmp(&done, Assembler::kNearJump);
- __ Bind(&is_equal);
- __ LoadObject(result, Bool::Get(kind == Token::kEQ));
- __ Bind(&done);
- } else {
- Condition cond = TokenKindToSmiCondition(kind);
- branch->EmitBranchOnCondition(compiler, cond);
- }
-}
-
-
-// First test if receiver is NULL, in which case === is applied.
-// If type feedback was provided (lists of <class-id, target>), do a
-// type by type check (either === or static call to the operator.
-static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
- LocationSummary* locs,
- Token::Kind kind,
- BranchInstr* branch,
- const ICData& ic_data,
- intptr_t deopt_id,
- intptr_t token_pos) {
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
- ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
- Register left = locs->in(0).reg();
- Register right = locs->in(1).reg();
- __ pushl(left);
- __ pushl(right);
- EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
- deopt_id, token_pos);
-}
-
-
static Condition FlipCondition(Condition condition) {
switch (condition) {
case EQUAL: return EQUAL;
@@ -766,27 +527,7 @@
EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
return;
}
- if (IsCheckedStrictEqual()) {
- EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
- deopt_id());
- return;
- }
- if (IsPolymorphic()) {
- EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
- deopt_id(), token_pos());
- return;
- }
- Register left = locs()->in(0).reg();
- Register right = locs()->in(1).reg();
- __ pushl(left);
- __ pushl(right);
- EmitEqualityAsInstanceCall(compiler,
- deopt_id(),
- token_pos(),
- kind(),
- locs(),
- *ic_data());
- ASSERT(locs()->out().reg() == EAX);
+ UNREACHABLE();
}
@@ -806,32 +547,7 @@
EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
return;
}
- if (IsCheckedStrictEqual()) {
- EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
- deopt_id());
- return;
- }
- if (IsPolymorphic()) {
- EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
- deopt_id(), token_pos());
- return;
- }
- Register left = locs()->in(0).reg();
- Register right = locs()->in(1).reg();
- __ pushl(left);
- __ pushl(right);
- EmitEqualityAsInstanceCall(compiler,
- deopt_id(),
- token_pos(),
- Token::kEQ, // kNE reverse occurs at branch.
- locs(),
- *ic_data());
- if (branch->is_checked()) {
- EmitAssertBoolean(EAX, token_pos(), deopt_id(), locs(), compiler);
- }
- Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
- __ CompareObject(EAX, Bool::True());
- branch->EmitBranchOnCondition(compiler, branch_condition);
+ UNREACHABLE();
}
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698