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

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 11363141: Improve smi shift operations and avoid repeated deoptimizations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_x64.cc
===================================================================
--- runtime/vm/intermediate_language_x64.cc (revision 14704)
+++ runtime/vm/intermediate_language_x64.cc (working copy)
@@ -1612,15 +1612,13 @@
summary->set_out(Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
- // Two Smi operands can easily overflow into Mint.
- const intptr_t kNumTemps = 2;
+ const intptr_t kNumTemps = 1;
LocationSummary* summary =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- summary->set_in(0, Location::RegisterLocation(RAX));
- summary->set_in(1, Location::RegisterLocation(RDX));
- summary->set_out(Location::RegisterLocation(RAX));
- summary->set_temp(0, Location::RegisterLocation(RBX));
- summary->set_temp(1, Location::RegisterLocation(RCX));
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::FixedRegisterOrConstant(right(), RCX));
+ summary->set_temp(0, Location::RequiresRegister());
+ summary->set_out(Location::SameAsFirstInput());
return summary;
} else {
const intptr_t kNumTemps = 0;
@@ -1697,6 +1695,28 @@
__ SmiTag(left);
break;
}
+ case Token::kSHL: {
+ // shlq operation masks the count to 6 bits.
+ const intptr_t kCountLimit = 0x3F;
+ intptr_t value = Smi::Cast(constant).Value();
+ if (value == 0) break;
+ if ((value < 0) || (value >= kCountLimit)) {
+ // This condition may not be known earlier in some cases because
+ // of constant propagation, inlining, etc.
+ __ jmp(deopt);
+ break;
+ }
+ Register temp = locs()->temp(0).reg();
+ __ movq(temp, left);
+ __ shlq(left, Immediate(value));
+ __ sarq(left, Immediate(value));
+ __ cmpq(left, temp);
+ __ j(NOT_EQUAL, deopt); // Overflow.
+ // Shift for result now we know there is no overflow.
+ __ shlq(left, Immediate(value));
+ break;
+ }
+
default:
UNREACHABLE();
break;
@@ -1780,7 +1800,6 @@
}
case Token::kSHL: {
Register temp = locs()->temp(0).reg();
- Label call_method, done;
// Check if count too large for handling it inlined.
__ movq(temp, left);
Range* right_range = this->right()->definition()->range();
@@ -1789,38 +1808,17 @@
if (right_needs_check) {
__ cmpq(right,
Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
- __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
+ __ j(ABOVE_EQUAL, deopt);
}
- Register right_temp = locs()->temp(1).reg();
- ASSERT(right_temp == RCX); // Count must be in RCX
- __ movq(right_temp, right);
- __ SmiUntag(right_temp);
+ ASSERT(right == RCX); // Count must be in RCX
+ __ SmiUntag(right);
// Overflow test (preserve temp and right);
- __ shlq(left, right_temp);
- __ sarq(left, right_temp);
+ __ shlq(left, right);
+ __ sarq(left, right);
__ cmpq(left, temp);
- __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
+ __ j(NOT_EQUAL, deopt); // Overflow.
// Shift for result now we know there is no overflow.
- __ shlq(left, right_temp);
- __ jmp(&done);
- {
- __ Bind(&call_method);
- Function& target = Function::ZoneHandle(
- ic_data()->GetTargetForReceiverClassId(kSmiCid));
- ASSERT(!target.IsNull());
- const intptr_t kArgumentCount = 2;
- __ pushq(temp);
- __ pushq(right);
- compiler->GenerateStaticCall(
- deopt_id(),
- instance_call()->token_pos(),
- target,
- kArgumentCount,
- Array::Handle(), // No argument names.
- locs());
- ASSERT(result == RAX);
- }
- __ Bind(&done);
+ __ shlq(left, right);
break;
}
case Token::kDIV: {
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698