30 #include "../include/v8stdint.h"
42 static int NormalizedExponent(uint64_t significand,
int exponent) {
45 significand = significand << 1;
46 exponent = exponent - 1;
54 static int EstimatePower(
int exponent);
57 static void InitialScaledStartValues(
double v,
59 bool need_boundary_deltas,
69 static void FixupMultiply10(
int estimated_power,
bool is_even,
71 Bignum* numerator, Bignum* denominator,
72 Bignum* delta_minus, Bignum* delta_plus);
75 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
76 Bignum* delta_minus, Bignum* delta_plus,
78 Vector<char> buffer,
int* length);
80 static void BignumToFixed(
int requested_digits,
int* decimal_point,
81 Bignum* numerator, Bignum* denominator,
82 Vector<char>(buffer),
int* length);
87 static void GenerateCountedDigits(
int count,
int* decimal_point,
88 Bignum* numerator, Bignum* denominator,
89 Vector<char>(buffer),
int* length);
97 bool is_even = (significand & 1) == 0;
99 int normalized_exponent = NormalizedExponent(significand, exponent);
101 int estimated_power = EstimatePower(normalized_exponent);
113 *decimal_point = -requested_digits;
127 InitialScaledStartValues(v, estimated_power, need_boundary_deltas,
128 &numerator, &denominator,
129 &delta_minus, &delta_plus);
131 FixupMultiply10(estimated_power, is_even, decimal_point,
132 &numerator, &denominator,
133 &delta_minus, &delta_plus);
138 GenerateShortestDigits(&numerator, &denominator,
139 &delta_minus, &delta_plus,
140 is_even, buffer, length);
143 BignumToFixed(requested_digits, decimal_point,
144 &numerator, &denominator,
148 GenerateCountedDigits(requested_digits, decimal_point,
149 &numerator, &denominator,
155 buffer[*length] =
'\0';
172 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
173 Bignum* delta_minus, Bignum* delta_plus,
175 Vector<char> buffer,
int* length) {
179 delta_plus = delta_minus;
184 digit = numerator->DivideModuloIntBignum(*denominator);
188 buffer[(*length)++] = digit +
'0';
195 bool in_delta_room_minus;
196 bool in_delta_room_plus;
200 in_delta_room_minus =
Bignum::Less(*numerator, *delta_minus);
209 if (!in_delta_room_minus && !in_delta_room_plus) {
211 numerator->Times10();
212 delta_minus->Times10();
216 if (delta_minus != delta_plus) {
217 delta_plus->Times10();
219 }
else if (in_delta_room_minus && in_delta_room_plus) {
225 }
else if (compare > 0) {
231 ASSERT(buffer[(*length) - 1] !=
'9');
232 buffer[(*length) - 1]++;
239 if ((buffer[(*length) - 1] -
'0') % 2 == 0) {
242 ASSERT(buffer[(*length) - 1] !=
'9');
243 buffer[(*length) - 1]++;
247 }
else if (in_delta_room_minus) {
256 ASSERT(buffer[(*length) -1] !=
'9');
257 buffer[(*length) - 1]++;
270 static void GenerateCountedDigits(
int count,
int* decimal_point,
271 Bignum* numerator, Bignum* denominator,
272 Vector<char>(buffer),
int* length) {
274 for (
int i = 0; i < count - 1; ++i) {
276 digit = numerator->DivideModuloIntBignum(*denominator);
280 buffer[i] = digit +
'0';
282 numerator->Times10();
286 digit = numerator->DivideModuloIntBignum(*denominator);
290 buffer[count - 1] = digit +
'0';
293 for (
int i = count - 1; i > 0; --i) {
294 if (buffer[i] !=
'0' + 10)
break;
298 if (buffer[0] ==
'0' + 10) {
312 static void BignumToFixed(
int requested_digits,
int* decimal_point,
313 Bignum* numerator, Bignum* denominator,
314 Vector<char>(buffer),
int* length) {
318 if (-(*decimal_point) > requested_digits) {
324 *decimal_point = -requested_digits;
327 }
else if (-(*decimal_point) == requested_digits) {
330 ASSERT(*decimal_point == -requested_digits);
333 denominator->Times10();
348 int needed_digits = (*decimal_point) + requested_digits;
349 GenerateCountedDigits(needed_digits, decimal_point,
350 numerator, denominator,
371 static int EstimatePower(
int exponent) {
393 const double k1Log10 = 0.30102999566398114;
396 const int kSignificandSize = 53;
398 std::ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
399 return static_cast<int>(estimate);
404 static void InitialScaledStartValuesPositiveExponent(
405 double v,
int estimated_power,
bool need_boundary_deltas,
406 Bignum* numerator, Bignum* denominator,
407 Bignum* delta_minus, Bignum* delta_plus) {
409 ASSERT(estimated_power >= 0);
414 numerator->AssignUInt64(Double(v).Significand());
415 numerator->ShiftLeft(Double(v).Exponent());
417 denominator->AssignPowerUInt16(10, estimated_power);
419 if (need_boundary_deltas) {
422 denominator->ShiftLeft(1);
423 numerator->ShiftLeft(1);
426 delta_plus->AssignUInt16(1);
427 delta_plus->ShiftLeft(Double(v).Exponent());
429 delta_minus->AssignUInt16(1);
430 delta_minus->ShiftLeft(Double(v).Exponent());
437 uint64_t v_bits = Double(v).AsUint64();
441 denominator->ShiftLeft(1);
442 numerator->ShiftLeft(1);
443 delta_plus->ShiftLeft(1);
450 static void InitialScaledStartValuesNegativeExponentPositivePower(
451 double v,
int estimated_power,
bool need_boundary_deltas,
452 Bignum* numerator, Bignum* denominator,
453 Bignum* delta_minus, Bignum* delta_plus) {
454 uint64_t significand = Double(v).Significand();
455 int exponent = Double(v).Exponent();
463 numerator->AssignUInt64(significand);
465 denominator->AssignPowerUInt16(10, estimated_power);
466 denominator->ShiftLeft(-exponent);
468 if (need_boundary_deltas) {
471 denominator->ShiftLeft(1);
472 numerator->ShiftLeft(1);
477 delta_plus->AssignUInt16(1);
479 delta_minus->AssignUInt16(1);
487 uint64_t v_bits = Double(v).AsUint64();
488 if ((v_bits & Double::kSignificandMask) == 0) {
491 denominator->ShiftLeft(1);
492 numerator->ShiftLeft(1);
493 delta_plus->ShiftLeft(1);
500 static void InitialScaledStartValuesNegativeExponentNegativePower(
501 double v,
int estimated_power,
bool need_boundary_deltas,
502 Bignum* numerator, Bignum* denominator,
503 Bignum* delta_minus, Bignum* delta_plus) {
504 const uint64_t kMinimalNormalizedExponent =
506 uint64_t significand = Double(v).Significand();
507 int exponent = Double(v).Exponent();
512 Bignum* power_ten = numerator;
513 power_ten->AssignPowerUInt16(10, -estimated_power);
515 if (need_boundary_deltas) {
519 delta_plus->AssignBignum(*power_ten);
520 delta_minus->AssignBignum(*power_ten);
528 ASSERT(numerator == power_ten);
529 numerator->MultiplyByUInt64(significand);
532 denominator->AssignUInt16(1);
533 denominator->ShiftLeft(-exponent);
535 if (need_boundary_deltas) {
538 numerator->ShiftLeft(1);
539 denominator->ShiftLeft(1);
547 uint64_t v_bits = Double(v).AsUint64();
548 if ((v_bits & Double::kSignificandMask) == 0 &&
552 numerator->ShiftLeft(1);
553 denominator->ShiftLeft(1);
554 delta_plus->ShiftLeft(1);
596 static void InitialScaledStartValues(
double v,
598 bool need_boundary_deltas,
602 Bignum* delta_plus) {
603 if (Double(v).Exponent() >= 0) {
604 InitialScaledStartValuesPositiveExponent(
605 v, estimated_power, need_boundary_deltas,
606 numerator, denominator, delta_minus, delta_plus);
607 }
else if (estimated_power >= 0) {
608 InitialScaledStartValuesNegativeExponentPositivePower(
609 v, estimated_power, need_boundary_deltas,
610 numerator, denominator, delta_minus, delta_plus);
612 InitialScaledStartValuesNegativeExponentNegativePower(
613 v, estimated_power, need_boundary_deltas,
614 numerator, denominator, delta_minus, delta_plus);
630 static void FixupMultiply10(
int estimated_power,
bool is_even,
632 Bignum* numerator, Bignum* denominator,
633 Bignum* delta_minus, Bignum* delta_plus) {
645 *decimal_point = estimated_power + 1;
647 *decimal_point = estimated_power;
648 numerator->Times10();
650 delta_minus->Times10();
651 delta_plus->AssignBignum(*delta_minus);
653 delta_minus->Times10();
654 delta_plus->Times10();
uint64_t Significand() const
static const uint64_t kExponentMask
static const uint64_t kHiddenBit
#define ASSERT(condition)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
static int PlusCompare(const Bignum &a, const Bignum &b, const Bignum &c)
static bool Equal(const Bignum &a, const Bignum &b)
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, Vector< char > buffer, int *length, int *decimal_point)
static bool Less(const Bignum &a, const Bignum &b)
#define V8_2PART_UINT64_C(a, b)
static const uint64_t kSignificandMask
static bool LessEqual(const Bignum &a, const Bignum &b)
static const int kMaxSignificantBits