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

Unified Diff: runtime/vm/intermediate_language_mips.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_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_mips.cc
===================================================================
--- runtime/vm/intermediate_language_mips.cc (revision 29797)
+++ runtime/vm/intermediate_language_mips.cc (working copy)
@@ -304,98 +304,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(A1));
- locs->set_in(1, Location::RegisterLocation(A0));
- locs->set_temp(0, Location::RegisterLocation(T0));
- locs->set_out(Location::RegisterLocation(V0));
- return locs;
- }
- const intptr_t kNumTemps = 1;
- LocationSummary* locs =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- locs->set_in(0, Location::RegisterLocation(A1));
- locs->set_in(1, Location::RegisterLocation(A0));
- locs->set_temp(0, Location::RegisterLocation(T0));
- locs->set_out(Location::RegisterLocation(V0));
- return locs;
+ UNREACHABLE();
+ return NULL;
}
-// A1: left.
-// A0: right.
-// Uses T0 to load ic_call_data.
-// Result in V0.
-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;
-
- __ TraceSimMsg("EmitEqualityAsInstanceCall");
- __ Comment("EmitEqualityAsInstanceCall");
-
- 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.
- __ BranchEqual(V0, Bool::True(), &true_label);
- __ LoadObject(V0, Bool::True());
- __ b(&done);
- __ Bind(&true_label);
- __ LoadObject(V0, Bool::False());
- __ Bind(&done);
- }
-}
-
-
static void LoadValueCid(FlowGraphCompiler* compiler,
Register value_cid_reg,
Register value_reg,
@@ -448,178 +361,6 @@
}
-// A1: left, also on stack.
-// A0: right, also on stack.
-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();
- ASSERT(left == A1);
- ASSERT(right == A0);
- Register temp = locs->temp(0).reg();
-
- __ TraceSimMsg("EmitEqualityAsPolymorphicCall");
- __ Comment("EmitEqualityAsPolymorphicCall");
-
- 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;
- if (i < len - 1) {
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), &next_test);
- } else {
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt);
- }
- const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
- if (target.Owner() == object_store->object_class()) {
- // Object.== is same as ===.
- __ Drop(2);
- __ slt(CMPRES1, left, right);
- __ slt(CMPRES2, right, left);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- EmitBranchAfterCompare(compiler, cond, &load_true);
- __ LoadObject(result, Bool::False());
- __ b(&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 is_true;
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
- __ beq(CMPRES, CMPRES2, &is_true);
- __ LoadObject(V0, Bool::True());
- __ b(&done);
- __ Bind(&is_true);
- __ LoadObject(V0, Bool::False());
- }
- } else {
- if (branch->is_checked()) {
- EmitAssertBoolean(V0, token_pos, deopt_id, locs, compiler);
- }
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
- branch->EmitBranchOnCondition(compiler, cond);
- }
- }
- if (i < len - 1) {
- __ b(&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);
-
- __ Comment("CheckedStrictEqual");
-
- __ andi(CMPRES, left, Immediate(kSmiTagMask));
- __ beq(CMPRES, ZR, deopt);
- // 'left' is not Smi.
- Label identity_compare;
- __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
- __ beq(right, CMPRES1, &identity_compare);
- __ beq(left, CMPRES1, &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++) {
- if (i == (len - 1)) {
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt);
- } else {
- __ BranchEqual(temp, ic_data.GetReceiverClassIdAt(i), &identity_compare);
- }
- }
- __ Bind(&identity_compare);
- __ subu(CMPRES1, left, right);
- if (branch == NULL) {
- Label done, is_equal;
- Register result = locs.out().reg();
- __ beq(CMPRES, ZR, &is_equal);
- // Not equal.
- __ LoadObject(result, Bool::Get(kind != Token::kEQ));
- __ b(&done);
- __ Bind(&is_equal);
- __ LoadObject(result, Bool::Get(kind == Token::kEQ));
- __ Bind(&done);
-
- } else {
- Condition cond = TokenKindToSmiCondition(kind);
- __ mov(CMPRES2, ZR);
- 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();
- __ TraceSimMsg("EmitGenericEqualityCompare");
- __ Comment("EmitGenericEqualityCompare");
- ASSERT(left == A1);
- ASSERT(right == A0);
- __ addiu(SP, SP, Immediate(-2 * kWordSize));
- __ sw(A1, Address(SP, 1 * kWordSize));
- __ sw(A0, Address(SP, 0 * kWordSize));
- EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
- deopt_id, token_pos);
-}
-
-
static Condition FlipCondition(Condition condition) {
switch (condition) {
case EQ: return EQ;
@@ -739,30 +480,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();
- ASSERT(left == A1);
- ASSERT(right == A0);
- __ addiu(SP, SP, Immediate(-2 * kWordSize));
- __ sw(A1, Address(SP, 1 * kWordSize));
- __ sw(A0, Address(SP, 0 * kWordSize));
- EmitEqualityAsInstanceCall(compiler,
- deopt_id(),
- token_pos(),
- kind(),
- locs(),
- *ic_data());
- ASSERT(locs()->out().reg() == V0);
+ UNREACHABLE();
}
@@ -784,35 +502,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();
- ASSERT(left == A1);
- ASSERT(right == A0);
- __ addiu(SP, SP, Immediate(-2 * kWordSize));
- __ sw(A1, Address(SP, 1 * kWordSize));
- __ sw(A0, Address(SP, 0 * kWordSize));
- EmitEqualityAsInstanceCall(compiler,
- deopt_id(),
- token_pos(),
- Token::kEQ, // kNE reverse occurs at branch.
- locs(),
- *ic_data());
- if (branch->is_checked()) {
- EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
- }
- Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
- branch->EmitBranchOnCondition(compiler, branch_condition);
+ UNREACHABLE();
}
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698