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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10702195: Equality compare should record two arguments in IC data. INline double equality comparison. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months 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.h ('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_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 9640)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -192,9 +192,8 @@
LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
- if (HasICData() &&
- (ic_data()->NumberOfChecks() == 1) &&
- (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
+ if (receiver_class_id() != kObject) {
+ ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble));
const intptr_t kNumTemps = 1;
LocationSummary* locs = new LocationSummary(kNumInputs,
kNumTemps,
@@ -233,6 +232,8 @@
}
+// Optional integer arguments can often be null. Null is not collected
+// by IC data. TODO(srdjan): Shall we collect null classes in ICData as well?
static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
EqualityCompareComp* comp) {
Register left = comp->locs()->in(0).reg();
@@ -241,10 +242,9 @@
Label* deopt = compiler->AddDeoptStub(comp->cid(),
comp->token_pos(),
comp->try_index(),
- kDeoptSmiCompareSmis,
+ kDeoptSmiCompareSmi,
left,
right);
- // TODO(srdjan): Should we always include NULL test (common case)?
__ movl(temp, left);
__ orl(temp, right);
__ testl(temp, Immediate(kSmiTagMask));
@@ -265,6 +265,36 @@
}
+// TODO(srdjan): Add support for mixed Smi/Double equality
+// (see LoadDoubleOrSmiToXmm).
+static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler,
+ EqualityCompareComp* comp) {
+ Register left = comp->locs()->in(0).reg();
+ Register right = comp->locs()->in(1).reg();
+ Register temp = comp->locs()->temp(0).reg();
+ Label* deopt = compiler->AddDeoptStub(comp->cid(),
+ comp->token_pos(),
+ comp->try_index(),
+ kDeoptDoubleCompareDouble,
+ left,
+ right);
+ Label done, is_false, is_true;
+ __ CompareClassId(left, kDouble, temp);
+ __ j(NOT_EQUAL, deopt);
+ __ CompareClassId(right, kDouble, temp);
+ __ j(NOT_EQUAL, deopt);
+ __ movsd(XMM0, FieldAddress(left, Double::value_offset()));
+ __ movsd(XMM1, FieldAddress(right, Double::value_offset()));
+ if (comp->is_fused_with_branch()) {
+ compiler->EmitDoubleCompareBranch(
+ EQUAL, XMM0, XMM1, comp->fused_with_branch());
+ } else {
+ compiler->EmitDoubleCompareBool(
+ EQUAL, XMM0, XMM1, comp->locs()->out().reg());
+ }
+}
+
+
static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
EqualityCompareComp* comp) {
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
@@ -297,7 +327,7 @@
Register left,
Register right) {
ASSERT(comp->HasICData());
- const ICData& ic_data = *comp->ic_data();
+ const ICData& ic_data = ICData::Handle(comp->ic_data()->AsUnaryClassChecks());
ASSERT(ic_data.NumberOfChecks() > 0);
ASSERT(ic_data.num_args_tested() == 1);
Label* deopt = compiler->AddDeoptStub(comp->cid(),
@@ -407,12 +437,14 @@
void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (HasICData() &&
- (ic_data()->NumberOfChecks() == 1) &&
- (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
+ if (receiver_class_id() == kSmi) {
EmitSmiEqualityCompare(compiler, this);
return;
}
+ if (receiver_class_id() == kDouble) {
+ EmitDoubleEqualityCompare(compiler, this);
+ return;
+ }
EmitGenericEqualityCompare(compiler, this);
}
@@ -461,7 +493,7 @@
Label* deopt = compiler->AddDeoptStub(comp->cid(),
comp->token_pos(),
comp->try_index(),
- kDeoptSmiCompareSmis,
+ kDeoptSmiCompareSmi,
left,
right);
__ movl(temp, left);
@@ -517,25 +549,12 @@
compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
Condition true_condition = TokenKindToDoubleCondition(comp->kind());
- __ comisd(XMM0, XMM1);
-
if (comp->is_fused_with_branch()) {
- BranchInstr* branch = comp->fused_with_branch();
- BlockEntryInstr* nan_result = branch->is_negated() ?
- branch->true_successor() : branch->false_successor();
- __ j(PARITY_EVEN, compiler->GetBlockLabel(nan_result));
- branch->EmitBranchOnCondition(compiler, true_condition);
+ compiler->EmitDoubleCompareBranch(
+ true_condition, XMM0, XMM1, comp->fused_with_branch());
} else {
- Register result = comp->locs()->out().reg();
- Label is_false, is_true, done;
- __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
- __ j(true_condition, &is_true, Assembler::kNearJump);
- __ Bind(&is_false);
- __ LoadObject(result, compiler->bool_false());
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, compiler->bool_true());
- __ Bind(&done);
+ compiler->EmitDoubleCompareBool(
+ true_condition, XMM0, XMM1, comp->locs()->out().reg());
}
}
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698