| Index: runtime/lib/math.cc
|
| ===================================================================
|
| --- runtime/lib/math.cc (revision 40060)
|
| +++ runtime/lib/math.cc (working copy)
|
| @@ -6,7 +6,6 @@
|
|
|
| #include "vm/bootstrap_natives.h"
|
|
|
| -#include "vm/bigint_operations.h"
|
| #include "vm/exceptions.h"
|
| #include "vm/native_entry.h"
|
| #include "vm/object.h"
|
| @@ -153,26 +152,34 @@
|
| GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0));
|
| uint64_t seed = 0;
|
| if (seed_int.IsBigint()) {
|
| - const Bigint& mask64 = Bigint::Handle(
|
| - BigintOperations::NewFromUint64(0xffffffffffffffffLL));
|
| Bigint& big_seed = Bigint::Handle();
|
| big_seed ^= seed_int.raw();
|
| uint64_t negate_mask = 0;
|
| + uint64_t borrow = 0;
|
| if (big_seed.IsNegative()) {
|
| // Negate bits to make seed positive.
|
| // Negate bits again (by xor with negate_mask) when extracted below,
|
| // to get original bits.
|
| negate_mask = 0xffffffffffffffffLL;
|
| - big_seed ^= BigintOperations::BitNot(big_seed);
|
| +
|
| + // Instead of computing ~big_seed here, we compute it on the fly below as
|
| + // follows: ~(-big_seed) == ~(~(big_seed-1)) == big_seed-1
|
| + borrow = 1;
|
| }
|
| - Bigint& low64 = Bigint::Handle();
|
| + const intptr_t used = big_seed.Used();
|
| + intptr_t digit = 0;
|
| do {
|
| - low64 = BigintOperations::BitAnd(big_seed, mask64);
|
| - ASSERT(BigintOperations::FitsIntoUint64(low64));
|
| - uint64_t chunk = BigintOperations::ToUint64(low64) ^ negate_mask;
|
| - seed = (seed * 1037) ^ mix64(chunk);
|
| - big_seed = BigintOperations::ShiftRight(big_seed, 64);
|
| - } while (!big_seed.IsZero());
|
| + uint64_t low64 = ((digit + 1) < used) ? big_seed.DigitAt(digit + 1) : 0;
|
| + low64 <<= 32;
|
| + low64 |= (digit < used) ? big_seed.DigitAt(digit) : 0;
|
| + low64 -= borrow;
|
| + if ((borrow == 1) && (low64 != 0xffffffffffffffffLL)) {
|
| + borrow = 0;
|
| + }
|
| + low64 ^= negate_mask;
|
| + seed = (seed * 1037) ^ mix64(low64);
|
| + digit += 2;
|
| + } while (digit < used);
|
| } else {
|
| seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value()));
|
| }
|
|
|