| Index: runtime/vm/intermediate_language_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_ia32.cc (revision 11450)
|
| +++ runtime/vm/intermediate_language_ia32.cc (working copy)
|
| @@ -544,9 +544,10 @@
|
| Register left = locs.in(0).reg();
|
| Register right = locs.in(1).reg();
|
| const bool left_is_smi = (branch == NULL) ?
|
| - false : (branch->left()->ResultCid() == kSmiCid);
|
| + false : (branch->computation()->left()->ResultCid() == kSmiCid);
|
| const bool right_is_smi = (branch == NULL) ?
|
| - false : (branch->right()->ResultCid() == kSmiCid);
|
| + false : (branch->computation()->right()->ResultCid() == kSmiCid);
|
| + // TODO(fschneider): Move smi smi checks outside this instruction.
|
| if (!left_is_smi || !right_is_smi) {
|
| Register temp = locs.temp(0).reg();
|
| Label* deopt = compiler->AddDeoptStub(deopt_id,
|
| @@ -619,6 +620,7 @@
|
|
|
|
|
| void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
|
| if (receiver_class_id() == kSmiCid) {
|
| // Deoptimizes if both arguments not Smi.
|
| EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
|
| @@ -641,22 +643,65 @@
|
| if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
|
| EmitGenericEqualityCompare(compiler, locs(), kind(), NULL, *ic_data(),
|
| deopt_id(), token_pos(), try_index());
|
| - } else {
|
| - Register left = locs()->in(0).reg();
|
| - Register right = locs()->in(1).reg();
|
| - __ pushl(left);
|
| - __ pushl(right);
|
| - EmitEqualityAsInstanceCall(compiler,
|
| - deopt_id(),
|
| - token_pos(),
|
| - try_index(),
|
| - kind(),
|
| - locs());
|
| - ASSERT(locs()->out().reg() == EAX);
|
| + return;
|
| }
|
| + Register left = locs()->in(0).reg();
|
| + Register right = locs()->in(1).reg();
|
| + __ pushl(left);
|
| + __ pushl(right);
|
| + EmitEqualityAsInstanceCall(compiler,
|
| + deopt_id(),
|
| + token_pos(),
|
| + try_index(),
|
| + kind(),
|
| + locs());
|
| + ASSERT(locs()->out().reg() == EAX);
|
| }
|
|
|
|
|
| +void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
|
| + BranchInstr* branch) {
|
| + ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
|
| + if (receiver_class_id() == kSmiCid) {
|
| + // Deoptimizes if both arguments not Smi.
|
| + EmitSmiComparisonOp(compiler, *locs(), kind(), branch,
|
| + deopt_id(), try_index());
|
| + return;
|
| + }
|
| + if (receiver_class_id() == kDoubleCid) {
|
| + // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
|
| + EmitDoubleComparisonOp(compiler, *locs(), kind(), branch,
|
| + deopt_id(), try_index());
|
| + return;
|
| + }
|
| + const bool is_checked_strict_equal =
|
| + HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
|
| + if (is_checked_strict_equal) {
|
| + EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
|
| + deopt_id(), try_index());
|
| + return;
|
| + }
|
| + if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
|
| + EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
|
| + deopt_id(), token_pos(), try_index());
|
| + return;
|
| + }
|
| + Register left = locs()->in(0).reg();
|
| + Register right = locs()->in(1).reg();
|
| + __ pushl(left);
|
| + __ pushl(right);
|
| + EmitEqualityAsInstanceCall(compiler,
|
| + deopt_id(),
|
| + token_pos(),
|
| + try_index(),
|
| + Token::kEQ, // kNE reverse occurs at branch.
|
| + locs());
|
| + Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
|
| + __ CompareObject(EAX, compiler->bool_true());
|
| + branch->EmitBranchOnCondition(compiler, branch_condition);
|
| +}
|
| +
|
| +
|
| LocationSummary* RelationalOpComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 2;
|
| if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) {
|
| @@ -722,7 +767,6 @@
|
| token_pos(),
|
| try_index(),
|
| locs());
|
| - ASSERT(locs()->out().reg() == EAX);
|
| return;
|
| }
|
| const String& function_name =
|
| @@ -741,10 +785,27 @@
|
| Array::ZoneHandle(), // No optional arguments.
|
| kNumArgsChecked,
|
| locs());
|
| - ASSERT(locs()->out().reg() == EAX);
|
| }
|
|
|
|
|
| +void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
|
| + BranchInstr* branch) {
|
| + if (operands_class_id() == kSmiCid) {
|
| + EmitSmiComparisonOp(compiler, *locs(), kind(), branch,
|
| + deopt_id(), try_index());
|
| + return;
|
| + }
|
| + if (operands_class_id() == kDoubleCid) {
|
| + EmitDoubleComparisonOp(compiler, *locs(), kind(), branch,
|
| + deopt_id(), try_index());
|
| + return;
|
| + }
|
| + EmitNativeCode(compiler);
|
| + __ CompareObject(EAX, compiler->bool_true());
|
| + branch->EmitBranchOnCondition(compiler, EQUAL);
|
| +}
|
| +
|
| +
|
| LocationSummary* NativeCallComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 0;
|
| const intptr_t kNumTemps = 3;
|
| @@ -2133,144 +2194,11 @@
|
| }
|
|
|
|
|
| -// TODO(srdjan): Move to shared.
|
| -static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) {
|
| - if (ic_data.num_args_tested() != 2) return false;
|
| - if (ic_data.NumberOfChecks() != 1) return false;
|
| - Function& target = Function::Handle();
|
| - GrowableArray<intptr_t> class_ids;
|
| - ic_data.GetCheckAt(0, &class_ids, &target);
|
| - return (class_ids[0] == class_id) && (class_ids[1] == class_id);
|
| -}
|
| -
|
| -
|
| -static bool IsCheckedStrictEquals(const ICData& ic_data, Token::Kind kind) {
|
| - if ((kind == Token::kEQ) || (kind == Token::kNE)) {
|
| - return ic_data.AllTargetsHaveSameOwner(kInstanceCid);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -
|
| -LocationSummary* BranchInstr::MakeLocationSummary() const {
|
| - if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
|
| - if (ICDataWithBothClassIds(*ic_data(), kSmiCid) ||
|
| - ICDataWithBothClassIds(*ic_data(), kDoubleCid) ||
|
| - IsCheckedStrictEquals(*ic_data(), kind())) {
|
| - const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 1;
|
| - LocationSummary* summary =
|
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| - summary->set_in(0, Location::RequiresRegister());
|
| - summary->set_in(1, Location::RequiresRegister());
|
| - summary->set_temp(0, Location::RequiresRegister());
|
| - return summary;
|
| - }
|
| - if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
|
| - const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 1;
|
| - LocationSummary* locs =
|
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
|
| - locs->set_in(0, Location::RegisterLocation(EAX));
|
| - locs->set_in(1, Location::RegisterLocation(ECX));
|
| - locs->set_temp(0, Location::RegisterLocation(EDX));
|
| - return locs;
|
| - }
|
| - // Otherwise polymorphic dispatch.
|
| - }
|
| - // Call.
|
| - const intptr_t kNumInputs = 2;
|
| - const intptr_t kNumTemps = 0;
|
| - LocationSummary* locs =
|
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
|
| - locs->set_in(0, Location::RegisterLocation(EAX));
|
| - locs->set_in(1, Location::RegisterLocation(ECX));
|
| - return locs;
|
| -}
|
| -
|
| -
|
| void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - // Relational or equality.
|
| - if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
|
| - if (ICDataWithBothClassIds(*ic_data(), kSmiCid)) {
|
| - EmitSmiComparisonOp(compiler, *locs(), kind(), this,
|
| - deopt_id(), try_index());
|
| - return;
|
| - }
|
| - if (ICDataWithBothClassIds(*ic_data(), kDoubleCid)) {
|
| - EmitDoubleComparisonOp(compiler, *locs(), kind(), this,
|
| - deopt_id(), try_index());
|
| - return;
|
| - }
|
| - if (IsCheckedStrictEquals(*ic_data(), kind())) {
|
| - EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this,
|
| - deopt_id(), try_index());
|
| - return;
|
| - }
|
| -
|
| - // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
|
| - if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
|
| - EmitGenericEqualityCompare(compiler, locs(), kind(), this, *ic_data(),
|
| - deopt_id(), token_pos(), try_index());
|
| - return;
|
| - }
|
| - // Otherwise polymorphic dispatch?
|
| - }
|
| - Register left = locs()->in(0).reg();
|
| - Register right = locs()->in(1).reg();
|
| - __ pushl(left);
|
| - __ pushl(right);
|
| - if ((kind() == Token::kNE) || (kind() == Token::kEQ)) {
|
| - EmitEqualityAsInstanceCall(compiler,
|
| - deopt_id(),
|
| - token_pos(),
|
| - try_index(),
|
| - Token::kEQ, // kNE reverse occurs at branch.
|
| - locs());
|
| - } else {
|
| - const String& function_name =
|
| - String::ZoneHandle(Symbols::New(Token::Str(kind())));
|
| - compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
|
| - deopt_id(),
|
| - token_pos(),
|
| - try_index());
|
| - const intptr_t kNumArguments = 2;
|
| - const intptr_t kNumArgsChecked = 2; // Type-feedback.
|
| - compiler->GenerateInstanceCall(deopt_id(),
|
| - token_pos(),
|
| - try_index(),
|
| - function_name,
|
| - kNumArguments,
|
| - Array::ZoneHandle(), // No optional args.
|
| - kNumArgsChecked,
|
| - locs());
|
| - }
|
| - Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
|
| - __ CompareObject(EAX, compiler->bool_true());
|
| - EmitBranchOnCondition(compiler, branch_condition);
|
| + computation()->EmitBranchCode(compiler, this);
|
| }
|
|
|
|
|
| -LocationSummary* StrictCompareAndBranchInstr::MakeLocationSummary() const {
|
| - const int kNumInputs = 2;
|
| - const int kNumTemps = 0;
|
| - LocationSummary* locs =
|
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| - locs->set_in(0, Location::RequiresRegister());
|
| - locs->set_in(1, Location::RequiresRegister());
|
| - return locs;
|
| -}
|
| -
|
| -
|
| -void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - Register left = locs()->in(0).reg();
|
| - Register right = locs()->in(1).reg();
|
| - __ cmpl(left, right);
|
| - Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
|
| - EmitBranchOnCondition(compiler, cond);
|
| -}
|
| -
|
| -
|
| LocationSummary* CheckClassComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 1;
|
| const intptr_t kNumTemps = 1;
|
|
|