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

Side by Side Diff: runtime/lib/math.cc

Issue 509153003: New bigint implementation in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 <ctype.h> // isspace. 5 #include <ctype.h> // isspace.
6 6
7 #include "vm/bootstrap_natives.h" 7 #include "vm/bootstrap_natives.h"
8 8
9 #include "vm/bigint_operations.h"
10 #include "vm/exceptions.h" 9 #include "vm/exceptions.h"
11 #include "vm/native_entry.h" 10 #include "vm/native_entry.h"
12 #include "vm/object.h" 11 #include "vm/object.h"
13 #include "vm/scanner.h" 12 #include "vm/scanner.h"
14 #include "vm/symbols.h" 13 #include "vm/symbols.h"
15 14
16 namespace dart { 15 namespace dart {
17 16
18 DEFINE_NATIVE_ENTRY(Math_sqrt, 1) { 17 DEFINE_NATIVE_ENTRY(Math_sqrt, 1) {
19 GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0)); 18 GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 // hash = 0x5A17; 145 // hash = 0x5A17;
147 // } 146 // }
148 // var result = new Uint32List(2); 147 // var result = new Uint32List(2);
149 // result[kSTATE_LO] = seed & _MASK_32; 148 // result[kSTATE_LO] = seed & _MASK_32;
150 // result[kSTATE_HI] = seed >> 32; 149 // result[kSTATE_HI] = seed >> 32;
151 // return result; 150 // return result;
152 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) { 151 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) {
153 GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0)); 152 GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0));
154 uint64_t seed = 0; 153 uint64_t seed = 0;
155 if (seed_int.IsBigint()) { 154 if (seed_int.IsBigint()) {
156 const Bigint& mask64 = Bigint::Handle(
157 BigintOperations::NewFromUint64(0xffffffffffffffffLL));
158 Bigint& big_seed = Bigint::Handle(); 155 Bigint& big_seed = Bigint::Handle();
159 big_seed ^= seed_int.raw(); 156 big_seed ^= seed_int.raw();
160 uint64_t negate_mask = 0; 157 uint64_t negate_mask = 0;
158 uint64_t borrow = 0;
161 if (big_seed.IsNegative()) { 159 if (big_seed.IsNegative()) {
162 // Negate bits to make seed positive. 160 // Negate bits to make seed positive.
163 // Negate bits again (by xor with negate_mask) when extracted below, 161 // Negate bits again (by xor with negate_mask) when extracted below,
164 // to get original bits. 162 // to get original bits.
165 negate_mask = 0xffffffffffffffffLL; 163 negate_mask = 0xffffffffffffffffLL;
166 big_seed ^= BigintOperations::BitNot(big_seed); 164
165 // Instead of computing ~big_seed here, we compute it on the fly below as
166 // follows: ~(-big_seed) == ~(~(big_seed-1)) == big_seed-1
167 borrow = 1;
167 } 168 }
168 Bigint& low64 = Bigint::Handle(); 169 const intptr_t used = big_seed.Used();
170 intptr_t digit = 0;
169 do { 171 do {
170 low64 = BigintOperations::BitAnd(big_seed, mask64); 172 uint64_t low64 = ((digit + 1) < used) ? big_seed.DigitAt(digit + 1) : 0;
171 ASSERT(BigintOperations::FitsIntoUint64(low64)); 173 low64 <<= 32;
172 uint64_t chunk = BigintOperations::ToUint64(low64) ^ negate_mask; 174 low64 |= (digit < used) ? big_seed.DigitAt(digit) : 0;
173 seed = (seed * 1037) ^ mix64(chunk); 175 low64 -= borrow;
174 big_seed = BigintOperations::ShiftRight(big_seed, 64); 176 if ((borrow == 1) && (low64 != 0xffffffffffffffffLL)) {
175 } while (!big_seed.IsZero()); 177 borrow = 0;
178 }
179 low64 ^= negate_mask;
180 seed = (seed * 1037) ^ mix64(low64);
181 digit += 2;
182 } while (digit < used);
176 } else { 183 } else {
177 seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value())); 184 seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value()));
178 } 185 }
179 186
180 if (seed == 0) { 187 if (seed == 0) {
181 seed = 0x5a17; 188 seed = 0x5a17;
182 } 189 }
183 return CreateRandomState(isolate, seed); 190 return CreateRandomState(isolate, seed);
184 } 191 }
185 192
186 193
187 DEFINE_NATIVE_ENTRY(Random_initialSeed, 0) { 194 DEFINE_NATIVE_ENTRY(Random_initialSeed, 0) {
188 Random* rnd = isolate->random(); 195 Random* rnd = isolate->random();
189 uint64_t seed = rnd->NextUInt32(); 196 uint64_t seed = rnd->NextUInt32();
190 seed |= (static_cast<uint64_t>(rnd->NextUInt32()) << 32); 197 seed |= (static_cast<uint64_t>(rnd->NextUInt32()) << 32);
191 return CreateRandomState(isolate, seed); 198 return CreateRandomState(isolate, seed);
192 } 199 }
193 200
194 } // namespace dart 201 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698