Index: runtime/vm/intermediate_language_arm.cc |
=================================================================== |
--- runtime/vm/intermediate_language_arm.cc (revision 29797) |
+++ runtime/vm/intermediate_language_arm.cc (working copy) |
@@ -315,87 +315,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(R1)); |
- locs->set_in(1, Location::RegisterLocation(R0)); |
- locs->set_temp(0, Location::RegisterLocation(R5)); |
- locs->set_out(Location::RegisterLocation(R0)); |
- return locs; |
- } |
- const intptr_t kNumTemps = 1; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- locs->set_in(0, Location::RegisterLocation(R1)); |
- locs->set_in(1, Location::RegisterLocation(R0)); |
- locs->set_temp(0, Location::RegisterLocation(R5)); |
- locs->set_out(Location::RegisterLocation(R0)); |
- 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) { |
- // Negate the condition: true label returns false and vice versa. |
- __ CompareObject(R0, Bool::True()); |
- __ LoadObject(R0, Bool::True(), NE); |
- __ LoadObject(R0, Bool::False(), EQ); |
- } |
-} |
- |
- |
static void LoadValueCid(FlowGraphCompiler* compiler, |
Register value_cid_reg, |
Register value_reg, |
@@ -434,154 +358,6 @@ |
} |
-// R1: left, also on stack. |
-// R0: 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 == R1); |
- ASSERT(right == R0); |
- 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; |
- __ CompareImmediate(temp, ic_data.GetReceiverClassIdAt(i)); |
- if (i < len - 1) { |
- __ b(&next_test, NE); |
- } else { |
- __ b(deopt, NE); |
- } |
- const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
- if (target.Owner() == object_store->object_class()) { |
- // Object.== is same as ===. |
- __ Drop(2); |
- __ cmp(left, ShifterOperand(right)); |
- if (branch != NULL) { |
- branch->EmitBranchOnCondition(compiler, cond); |
- } else { |
- Register result = locs->out().reg(); |
- __ LoadObject(result, Bool::True(), cond); |
- __ LoadObject(result, Bool::False(), NegateCondition(cond)); |
- } |
- } 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) { |
- __ CompareObject(R0, Bool::True()); |
- __ LoadObject(R0, Bool::True(), NE); |
- __ LoadObject(R0, Bool::False(), EQ); |
- } |
- } else { |
- if (branch->is_checked()) { |
- EmitAssertBoolean(R0, token_pos, deopt_id, locs, compiler); |
- } |
- __ CompareObject(R0, 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); |
- __ tst(left, ShifterOperand(kSmiTagMask)); |
- __ b(deopt, EQ); |
- // 'left' is not Smi. |
- Label identity_compare; |
- __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
- __ cmp(right, ShifterOperand(IP)); |
- __ b(&identity_compare, EQ); |
- __ cmp(left, ShifterOperand(IP)); |
- __ b(&identity_compare, EQ); |
- |
- __ 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++) { |
- __ CompareImmediate(temp, ic_data.GetReceiverClassIdAt(i)); |
- if (i == (len - 1)) { |
- __ b(deopt, NE); |
- } else { |
- __ b(&identity_compare, EQ); |
- } |
- } |
- __ Bind(&identity_compare); |
- __ cmp(left, ShifterOperand(right)); |
- if (branch == NULL) { |
- Register result = locs.out().reg(); |
- __ LoadObject(result, Bool::Get(kind == Token::kEQ), EQ); |
- __ LoadObject(result, Bool::Get(kind != Token::kEQ), NE); |
- } 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(); |
- ASSERT(left == R1); |
- ASSERT(right == R0); |
- __ PushList((1 << R0) | (1 << R1)); |
- EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, |
- deopt_id, token_pos); |
-} |
- |
- |
static Condition FlipCondition(Condition condition) { |
switch (condition) { |
case EQ: return EQ; |
@@ -694,28 +470,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 == R1); |
- ASSERT(right == R0); |
- __ PushList((1 << R0) | (1 << R1)); |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- kind(), |
- locs(), |
- *ic_data()); |
- ASSERT(locs()->out().reg() == R0); |
+ UNREACHABLE(); |
} |
@@ -735,33 +490,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 == R1); |
- ASSERT(right == R0); |
- __ PushList((1 << R0) | (1 << R1)); |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- Token::kEQ, // kNE reverse occurs at branch. |
- locs(), |
- *ic_data()); |
- if (branch->is_checked()) { |
- EmitAssertBoolean(R0, token_pos(), deopt_id(), locs(), compiler); |
- } |
- Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; |
- __ CompareObject(R0, Bool::True()); |
- branch->EmitBranchOnCondition(compiler, branch_condition); |
+ UNREACHABLE(); |
} |