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

Unified Diff: runtime/vm/object.cc

Issue 381543002: Tweaks for speed in integer arithmetic runtime. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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/platform/utils.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 38076)
+++ runtime/vm/object.cc (working copy)
@@ -15228,8 +15228,7 @@
// In 32-bit mode, the result of any operation between two Smis will fit in a
// 32-bit signed result, except the product of two Smis, which will be 64-bit.
// In 64-bit mode, the result of any operation between two Smis will fit in a
- // 64-bit signed result, except the product of two Smis (unless the Smis are
- // 32-bit or less).
+ // 64-bit signed result, except the product of two Smis (see below).
if (IsSmi() && other.IsSmi()) {
const intptr_t left_value = Smi::Value(Smi::RawCast(raw()));
const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw()));
@@ -15244,10 +15243,12 @@
return Integer::New(static_cast<int64_t>(left_value) *
static_cast<int64_t>(right_value));
} else {
- // In 64-bit mode, the product of two 32-bit signed integers fits in a
- // 64-bit result.
+ // In 64-bit mode, the product of two signed integers fits in a
+ // 64-bit result if the sum of the highest bits of their absolute
+ // values is smaller than 62.
ASSERT(sizeof(intptr_t) == sizeof(int64_t));
- if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) {
+ if ((Utils::HighestBit(left_value) +
+ Utils::HighestBit(right_value)) < 62) {
return Integer::New(left_value * right_value);
}
}
@@ -15271,43 +15272,42 @@
UNIMPLEMENTED();
}
}
- // In 32-bit mode, the result of any operation between two 63-bit signed
- // integers (or 32-bit for multiplication) will fit in a 64-bit signed result.
+ // In 32-bit mode, the result of any operation (except multiplication) between
+ // two 63-bit signed integers will fit in a 64-bit signed result.
+ // For the multiplication result to fit, the sum of the highest bits of the
+ // absolute values of the operands must be smaller than 62.
// In 64-bit mode, 63-bit signed integers are Smis, already processed above.
if ((Smi::kBits < 32) && !IsBigint() && !other.IsBigint()) {
const int64_t left_value = AsInt64Value();
- if (Utils::IsInt(63, left_value)) {
- const int64_t right_value = other.AsInt64Value();
- if (Utils::IsInt(63, right_value)) {
- switch (operation) {
- case Token::kADD:
- return Integer::New(left_value + right_value);
- case Token::kSUB:
- return Integer::New(left_value - right_value);
- case Token::kMUL: {
- if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) {
- return Integer::New(left_value * right_value);
+ const int64_t right_value = other.AsInt64Value();
+ if (operation == Token::kMUL) {
+ if ((Utils::HighestBit(left_value) +
+ Utils::HighestBit(right_value)) < 62) {
+ return Integer::New(left_value * right_value);
+ }
+ // Perform a Bigint multiplication below.
+ } else if (Utils::IsInt(63, left_value) && Utils::IsInt(63, right_value)) {
+ switch (operation) {
+ case Token::kADD:
+ return Integer::New(left_value + right_value);
+ case Token::kSUB:
+ return Integer::New(left_value - right_value);
+ case Token::kTRUNCDIV:
+ return Integer::New(left_value / right_value);
+ case Token::kMOD: {
+ const int64_t remainder = left_value % right_value;
+ if (remainder < 0) {
+ if (right_value < 0) {
+ return Integer::New(remainder - right_value);
+ } else {
+ return Integer::New(remainder + right_value);
}
- // Perform a Bigint multiplication below.
- break;
}
- case Token::kTRUNCDIV:
- return Integer::New(left_value / right_value);
- case Token::kMOD: {
- const int64_t remainder = left_value % right_value;
- if (remainder < 0) {
- if (right_value < 0) {
- return Integer::New(remainder - right_value);
- } else {
- return Integer::New(remainder + right_value);
- }
- }
- return Integer::New(remainder);
- }
- default:
- UNIMPLEMENTED();
- }
+ return Integer::New(remainder);
}
+ default:
+ UNIMPLEMENTED();
+ }
}
}
const Bigint& left_big = Bigint::Handle(AsBigint());
« no previous file with comments | « runtime/platform/utils.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698