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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« runtime/lib/integers.cc ('K') | « runtime/platform/utils.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 15210 matching lines...) Expand 10 before | Expand all | Expand 10 after
15221 return big_value.raw(); 15221 return big_value.raw();
15222 } 15222 }
15223 } 15223 }
15224 15224
15225 15225
15226 RawInteger* Integer::ArithmeticOp(Token::Kind operation, 15226 RawInteger* Integer::ArithmeticOp(Token::Kind operation,
15227 const Integer& other) const { 15227 const Integer& other) const {
15228 // In 32-bit mode, the result of any operation between two Smis will fit in a 15228 // In 32-bit mode, the result of any operation between two Smis will fit in a
15229 // 32-bit signed result, except the product of two Smis, which will be 64-bit. 15229 // 32-bit signed result, except the product of two Smis, which will be 64-bit.
15230 // In 64-bit mode, the result of any operation between two Smis will fit in a 15230 // In 64-bit mode, the result of any operation between two Smis will fit in a
15231 // 64-bit signed result, except the product of two Smis (unless the Smis are 15231 // 64-bit signed result, except the product of two Smis (see below).
15232 // 32-bit or less).
15233 if (IsSmi() && other.IsSmi()) { 15232 if (IsSmi() && other.IsSmi()) {
15234 const intptr_t left_value = Smi::Value(Smi::RawCast(raw())); 15233 const intptr_t left_value = Smi::Value(Smi::RawCast(raw()));
15235 const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw())); 15234 const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw()));
15236 switch (operation) { 15235 switch (operation) {
15237 case Token::kADD: 15236 case Token::kADD:
15238 return Integer::New(left_value + right_value); 15237 return Integer::New(left_value + right_value);
15239 case Token::kSUB: 15238 case Token::kSUB:
15240 return Integer::New(left_value - right_value); 15239 return Integer::New(left_value - right_value);
15241 case Token::kMUL: { 15240 case Token::kMUL: {
15242 if (Smi::kBits < 32) { 15241 if (Smi::kBits < 32) {
15243 // In 32-bit mode, the product of two Smis fits in a 64-bit result. 15242 // In 32-bit mode, the product of two Smis fits in a 64-bit result.
15244 return Integer::New(static_cast<int64_t>(left_value) * 15243 return Integer::New(static_cast<int64_t>(left_value) *
15245 static_cast<int64_t>(right_value)); 15244 static_cast<int64_t>(right_value));
15246 } else { 15245 } else {
15247 // In 64-bit mode, the product of two 32-bit signed integers fits in a 15246 // In 64-bit mode, the product of two signed integers fits in a
15248 // 64-bit result. 15247 // 64-bit result if the sum of the highest bits of their absolute
15248 // values is smaller than 62.
15249 ASSERT(sizeof(intptr_t) == sizeof(int64_t)); 15249 ASSERT(sizeof(intptr_t) == sizeof(int64_t));
15250 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { 15250 if ((Utils::HighestBit(left_value) +
15251 Utils::HighestBit(right_value)) < 62) {
15251 return Integer::New(left_value * right_value); 15252 return Integer::New(left_value * right_value);
15252 } 15253 }
15253 } 15254 }
15254 // Perform a Bigint multiplication below. 15255 // Perform a Bigint multiplication below.
15255 break; 15256 break;
15256 } 15257 }
15257 case Token::kTRUNCDIV: 15258 case Token::kTRUNCDIV:
15258 return Integer::New(left_value / right_value); 15259 return Integer::New(left_value / right_value);
15259 case Token::kMOD: { 15260 case Token::kMOD: {
15260 const intptr_t remainder = left_value % right_value; 15261 const intptr_t remainder = left_value % right_value;
15261 if (remainder < 0) { 15262 if (remainder < 0) {
15262 if (right_value < 0) { 15263 if (right_value < 0) {
15263 return Integer::New(remainder - right_value); 15264 return Integer::New(remainder - right_value);
15264 } else { 15265 } else {
15265 return Integer::New(remainder + right_value); 15266 return Integer::New(remainder + right_value);
15266 } 15267 }
15267 } 15268 }
15268 return Integer::New(remainder); 15269 return Integer::New(remainder);
15269 } 15270 }
15270 default: 15271 default:
15271 UNIMPLEMENTED(); 15272 UNIMPLEMENTED();
15272 } 15273 }
15273 } 15274 }
15274 // In 32-bit mode, the result of any operation between two 63-bit signed 15275 // In 32-bit mode, the result of any operation (except multiplication) between
15275 // integers (or 32-bit for multiplication) will fit in a 64-bit signed result. 15276 // two 63-bit signed integers will fit in a 64-bit signed result.
15277 // For the multiplication result to fit, the sum of the highest bits of the
15278 // absolute values of the operands must be smaller than 62.
15276 // In 64-bit mode, 63-bit signed integers are Smis, already processed above. 15279 // In 64-bit mode, 63-bit signed integers are Smis, already processed above.
15277 if ((Smi::kBits < 32) && !IsBigint() && !other.IsBigint()) { 15280 if ((Smi::kBits < 32) && !IsBigint() && !other.IsBigint()) {
15278 const int64_t left_value = AsInt64Value(); 15281 const int64_t left_value = AsInt64Value();
15279 if (Utils::IsInt(63, left_value)) { 15282 const int64_t right_value = other.AsInt64Value();
15280 const int64_t right_value = other.AsInt64Value(); 15283 if (operation == Token::kMUL) {
15281 if (Utils::IsInt(63, right_value)) { 15284 if ((Utils::HighestBit(left_value) +
15282 switch (operation) { 15285 Utils::HighestBit(right_value)) < 62) {
15283 case Token::kADD: 15286 return Integer::New(left_value * right_value);
15284 return Integer::New(left_value + right_value); 15287 }
15285 case Token::kSUB: 15288 // Perform a Bigint multiplication below.
15286 return Integer::New(left_value - right_value); 15289 } else if (Utils::IsInt(63, left_value) && Utils::IsInt(63, right_value)) {
15287 case Token::kMUL: { 15290 switch (operation) {
15288 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { 15291 case Token::kADD:
15289 return Integer::New(left_value * right_value); 15292 return Integer::New(left_value + right_value);
15293 case Token::kSUB:
15294 return Integer::New(left_value - right_value);
15295 case Token::kTRUNCDIV:
15296 return Integer::New(left_value / right_value);
15297 case Token::kMOD: {
15298 const int64_t remainder = left_value % right_value;
15299 if (remainder < 0) {
15300 if (right_value < 0) {
15301 return Integer::New(remainder - right_value);
15302 } else {
15303 return Integer::New(remainder + right_value);
15290 } 15304 }
15291 // Perform a Bigint multiplication below.
15292 break;
15293 } 15305 }
15294 case Token::kTRUNCDIV: 15306 return Integer::New(remainder);
15295 return Integer::New(left_value / right_value); 15307 }
15296 case Token::kMOD: { 15308 default:
15297 const int64_t remainder = left_value % right_value; 15309 UNIMPLEMENTED();
15298 if (remainder < 0) {
15299 if (right_value < 0) {
15300 return Integer::New(remainder - right_value);
15301 } else {
15302 return Integer::New(remainder + right_value);
15303 }
15304 }
15305 return Integer::New(remainder);
15306 }
15307 default:
15308 UNIMPLEMENTED();
15309 }
15310 } 15310 }
15311 } 15311 }
15312 } 15312 }
15313 const Bigint& left_big = Bigint::Handle(AsBigint()); 15313 const Bigint& left_big = Bigint::Handle(AsBigint());
15314 const Bigint& right_big = Bigint::Handle(other.AsBigint()); 15314 const Bigint& right_big = Bigint::Handle(other.AsBigint());
15315 const Bigint& result = 15315 const Bigint& result =
15316 Bigint::Handle(left_big.BigArithmeticOp(operation, right_big)); 15316 Bigint::Handle(left_big.BigArithmeticOp(operation, right_big));
15317 return Integer::Handle(result.AsValidInteger()).raw(); 15317 return Integer::Handle(result.AsValidInteger()).raw();
15318 } 15318 }
15319 15319
(...skipping 3734 matching lines...) Expand 10 before | Expand all | Expand 10 after
19054 return tag_label.ToCString(); 19054 return tag_label.ToCString();
19055 } 19055 }
19056 19056
19057 19057
19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19059 Instance::PrintJSONImpl(stream, ref); 19059 Instance::PrintJSONImpl(stream, ref);
19060 } 19060 }
19061 19061
19062 19062
19063 } // namespace dart 19063 } // namespace dart
OLDNEW
« runtime/lib/integers.cc ('K') | « runtime/platform/utils.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698