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

Side by Side Diff: src/conversions.cc

Issue 1367004: Optimization for parsing integers of limited length (in digits). (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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
« no previous file with comments | « no previous file | test/mjsunit/parse-int-float.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 const int kBufferSize = kMaxSignificantDigits + 10; 370 const int kBufferSize = kMaxSignificantDigits + 10;
371 char buffer[kBufferSize]; // NOLINT: size is known at compile time. 371 char buffer[kBufferSize]; // NOLINT: size is known at compile time.
372 int buffer_pos = 0; 372 int buffer_pos = 0;
373 373
374 // Exponent will be adjusted if insignificant digits of the integer part 374 // Exponent will be adjusted if insignificant digits of the integer part
375 // or insignificant leading zeros of the fractional part are dropped. 375 // or insignificant leading zeros of the fractional part are dropped.
376 int exponent = 0; 376 int exponent = 0;
377 int significant_digits = 0; 377 int significant_digits = 0;
378 int insignificant_digits = 0; 378 int insignificant_digits = 0;
379 bool nonzero_digit_dropped = false; 379 bool nonzero_digit_dropped = false;
380 bool fractional_part = false;
380 381
381 double signed_zero = 0.0; 382 double signed_zero = 0.0;
382 383
383 if (*current == '+') { 384 if (*current == '+') {
384 // Ignore leading sign; skip following spaces. 385 // Ignore leading sign; skip following spaces.
385 ++current; 386 ++current;
386 if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE; 387 if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
387 } else if (*current == '-') { 388 } else if (*current == '-') {
388 buffer[buffer_pos++] = '-'; 389 buffer[buffer_pos++] = '-';
389 ++current; 390 ++current;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 octal = octal && *current < '8'; 448 octal = octal && *current < '8';
448 ++current; 449 ++current;
449 if (current == end) goto parsing_done; 450 if (current == end) goto parsing_done;
450 } 451 }
451 452
452 if (significant_digits == 0) { 453 if (significant_digits == 0) {
453 octal = false; 454 octal = false;
454 } 455 }
455 456
456 if (*current == '.') { 457 if (*current == '.') {
457 ASSERT(buffer_pos < kBufferSize);
458 buffer[buffer_pos++] = '.';
459 ++current; 458 ++current;
460 if (current == end) { 459 if (current == end) {
461 if (significant_digits == 0 && !leading_zero) { 460 if (significant_digits == 0 && !leading_zero) {
462 return JUNK_STRING_VALUE; 461 return JUNK_STRING_VALUE;
463 } else { 462 } else {
464 goto parsing_done; 463 goto parsing_done;
465 } 464 }
466 } 465 }
467 466
468 if (significant_digits == 0) { 467 if (significant_digits == 0) {
469 // octal = false; 468 // octal = false;
470 // Integer part consists of 0 or is absent. Significant digits start after 469 // Integer part consists of 0 or is absent. Significant digits start after
471 // leading zeros (if any). 470 // leading zeros (if any).
472 while (*current == '0') { 471 while (*current == '0') {
473 ++current; 472 ++current;
474 if (current == end) return signed_zero; 473 if (current == end) return signed_zero;
475 exponent--; // Move this 0 into the exponent. 474 exponent--; // Move this 0 into the exponent.
476 } 475 }
477 } 476 }
478 477
478 ASSERT(buffer_pos < kBufferSize);
479 buffer[buffer_pos++] = '.';
480 fractional_part = true;
481
479 // There is the fractional part. 482 // There is the fractional part.
480 while (*current >= '0' && *current <= '9') { 483 while (*current >= '0' && *current <= '9') {
481 if (significant_digits < kMaxSignificantDigits) { 484 if (significant_digits < kMaxSignificantDigits) {
482 ASSERT(buffer_pos < kBufferSize); 485 ASSERT(buffer_pos < kBufferSize);
483 buffer[buffer_pos++] = static_cast<char>(*current); 486 buffer[buffer_pos++] = static_cast<char>(*current);
484 significant_digits++; 487 significant_digits++;
485 } else { 488 } else {
486 // Ignore insignificant digits in the fractional part. 489 // Ignore insignificant digits in the fractional part.
487 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 490 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
488 } 491 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 result *= pow(8.0, insignificant_digits); 576 result *= pow(8.0, insignificant_digits);
574 } 577 }
575 return result; 578 return result;
576 } 579 }
577 580
578 if (nonzero_digit_dropped) { 581 if (nonzero_digit_dropped) {
579 if (insignificant_digits) buffer[buffer_pos++] = '.'; 582 if (insignificant_digits) buffer[buffer_pos++] = '.';
580 buffer[buffer_pos++] = '1'; 583 buffer[buffer_pos++] = '1';
581 } 584 }
582 585
586 // If the number has no more than kMaxDigitsInInt digits and doesn't have
587 // fractional part it could be parsed faster (without checks for
588 // spaces, overflow, etc.).
589 const int kMaxDigitsInInt = 9 * sizeof(int) / 4; // NOLINT
590
583 if (exponent != 0) { 591 if (exponent != 0) {
584 ASSERT(buffer_pos < kBufferSize); 592 ASSERT(buffer_pos < kBufferSize);
585 buffer[buffer_pos++] = 'e'; 593 buffer[buffer_pos++] = 'e';
586 if (exponent < 0) { 594 if (exponent < 0) {
587 ASSERT(buffer_pos < kBufferSize); 595 ASSERT(buffer_pos < kBufferSize);
588 buffer[buffer_pos++] = '-'; 596 buffer[buffer_pos++] = '-';
589 exponent = -exponent; 597 exponent = -exponent;
590 } 598 }
591 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0. 599 if (exponent > 999) exponent = 999; // Result will be Infinity or 0 or -0.
592 600
593 const int exp_digits = 3; 601 const int exp_digits = 3;
594 for (int i = 0; i < exp_digits; i++) { 602 for (int i = 0; i < exp_digits; i++) {
595 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; 603 buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10;
596 exponent /= 10; 604 exponent /= 10;
597 } 605 }
598 ASSERT(exponent == 0); 606 ASSERT(exponent == 0);
599 buffer_pos += exp_digits; 607 buffer_pos += exp_digits;
608 } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) {
609 if (significant_digits == 0) return signed_zero;
610 ASSERT(buffer_pos > 0);
611 int num = 0;
612 int start_pos = (buffer[0] == '-' ? 1 : 0);
613 for (int i = start_pos; i < buffer_pos; i++) {
614 ASSERT(buffer[i] >= '0' && buffer[i] <= '9');
615 num = 10 * num + (buffer[i] - '0');
616 }
617 return static_cast<double>(start_pos == 0 ? num : -num);
600 } 618 }
601 619
602 ASSERT(buffer_pos < kBufferSize); 620 ASSERT(buffer_pos < kBufferSize);
603 buffer[buffer_pos] = '\0'; 621 buffer[buffer_pos] = '\0';
604 622
605 return gay_strtod(buffer, NULL); 623 return gay_strtod(buffer, NULL);
606 } 624 }
607 625
608 double StringToDouble(String* str, int flags, double empty_string_val) { 626 double StringToDouble(String* str, int flags, double empty_string_val) {
609 StringShape shape(str); 627 StringShape shape(str);
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 // Allocate result and fill in the parts. 1006 // Allocate result and fill in the parts.
989 StringBuilder builder(result_size + 1); 1007 StringBuilder builder(result_size + 1);
990 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); 1008 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size);
991 if (decimal_pos > 0) builder.AddCharacter('.'); 1009 if (decimal_pos > 0) builder.AddCharacter('.');
992 builder.AddSubstring(decimal_buffer, decimal_pos); 1010 builder.AddSubstring(decimal_buffer, decimal_pos);
993 return builder.Finalize(); 1011 return builder.Finalize();
994 } 1012 }
995 1013
996 1014
997 } } // namespace v8::internal 1015 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/parse-int-float.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698