| 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();
|
| }
|
|
|
|
|
|
|