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

Side by Side Diff: src/runtime.cc

Issue 7261008: Improvement to SmiLexicalCompare (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 6 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
« src/misc-intrinsics.h ('K') | « src/runtime.h ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 27 matching lines...) Expand all
38 #include "cpu.h" 38 #include "cpu.h"
39 #include "dateparser-inl.h" 39 #include "dateparser-inl.h"
40 #include "debug.h" 40 #include "debug.h"
41 #include "deoptimizer.h" 41 #include "deoptimizer.h"
42 #include "execution.h" 42 #include "execution.h"
43 #include "global-handles.h" 43 #include "global-handles.h"
44 #include "jsregexp.h" 44 #include "jsregexp.h"
45 #include "json-parser.h" 45 #include "json-parser.h"
46 #include "liveedit.h" 46 #include "liveedit.h"
47 #include "liveobjectlist-inl.h" 47 #include "liveobjectlist-inl.h"
48 #include "misc-intrinsics.h"
48 #include "parser.h" 49 #include "parser.h"
49 #include "platform.h" 50 #include "platform.h"
50 #include "runtime-profiler.h" 51 #include "runtime-profiler.h"
51 #include "runtime.h" 52 #include "runtime.h"
52 #include "scopeinfo.h" 53 #include "scopeinfo.h"
53 #include "smart-pointer.h" 54 #include "smart-pointer.h"
54 #include "string-search.h" 55 #include "string-search.h"
55 #include "stub-cache.h" 56 #include "stub-cache.h"
56 #include "v8threads.h" 57 #include "v8threads.h"
57 #include "vm-state-inl.h" 58 #include "vm-state-inl.h"
(...skipping 6582 matching lines...) Expand 10 before | Expand all | Expand 10 after
6640 6641
6641 // Extract the integer values from the Smis. 6642 // Extract the integer values from the Smis.
6642 CONVERT_CHECKED(Smi, x, args[0]); 6643 CONVERT_CHECKED(Smi, x, args[0]);
6643 CONVERT_CHECKED(Smi, y, args[1]); 6644 CONVERT_CHECKED(Smi, y, args[1]);
6644 int x_value = x->value(); 6645 int x_value = x->value();
6645 int y_value = y->value(); 6646 int y_value = y->value();
6646 6647
6647 // If the integers are equal so are the string representations. 6648 // If the integers are equal so are the string representations.
6648 if (x_value == y_value) return Smi::FromInt(EQUAL); 6649 if (x_value == y_value) return Smi::FromInt(EQUAL);
6649 6650
6650 // If one of the integers are zero the normal integer order is the 6651 // If one of the integers is zero the normal integer order is the
6651 // same as the lexicographic order of the string representations. 6652 // same as the lexicographic order of the string representations.
6652 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); 6653 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
6653 6654
6654 // If only one of the integers is negative the negative number is 6655 // If only one of the integers is negative the negative number is
6655 // smallest because the char code of '-' is less than the char code 6656 // smallest because the char code of '-' is less than the char code
6656 // of any digit. Otherwise, we make both values positive. 6657 // of any digit. Otherwise, we make both values positive.
6657 if (x_value < 0 || y_value < 0) { 6658 if (x_value < 0 || y_value < 0) {
6658 if (y_value >= 0) return Smi::FromInt(LESS); 6659 if (y_value >= 0) return Smi::FromInt(LESS);
6659 if (x_value >= 0) return Smi::FromInt(GREATER); 6660 if (x_value >= 0) return Smi::FromInt(GREATER);
6660 x_value = -x_value; 6661 x_value = -x_value;
6661 y_value = -y_value; 6662 y_value = -y_value;
6662 } 6663 }
6663 6664
6664 // Arrays for the individual characters of the two Smis. Smis are 6665 static const int powersOf10[] = { 1, 10, 100, 1000, 10*1000, 100*1000,
Erik Corry 2011/06/25 11:12:03 This is a constant so it should be named as a cons
sra1 2011/06/25 19:31:33 Done.
6665 // 31 bit integers and 10 decimal digits are therefore enough. 6666 1000*1000, 10*1000*1000, 100*1000*1000,
6666 // TODO(isolates): maybe we should simply allocate 20 bytes on the stack. 6667 1000*1000*1000 };
6667 int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms();
6668 int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms();
6669 6668
6669 // If the integers have the same number of decimal digits they can be
6670 // compared directly as the numeric order is the same as the
6671 // lexicographic order. If one integer has fewer digits, it is scaled
6672 // by some power of 10 to have the same number of digits as the longer
6673 // integer. If the scaled integers are equal it means the shorter
6674 // integer comes first in the lexicographic order.
6670 6675
6671 // Convert the integers to arrays of their decimal digits. 6676 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6672 int x_index = 0; 6677 int x_log2 = IntegerLog2(x_value);
6673 int y_index = 0; 6678 int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6674 while (x_value > 0) { 6679 x_log10 -= x_value < powersOf10[x_log10];
6675 x_elms[x_index++] = x_value % 10; 6680
6681 int y_log2 = IntegerLog2(y_value);
6682 int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6683 y_log10 -= y_value < powersOf10[y_log10];
6684
6685 int tie = EQUAL;
6686
6687 if (x_log10 < y_log10) {
6688 // X has fewer digits. We would like to simply scale up X but that
6689 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6690 // be scaled up to 9_000_000_000. So we scale up by the next
6691 // smallest power and scale down Y to drop one digit. It is OK to
6692 // drop one digit from the longer integer since the final digit is
6693 // past the length of the shorter integer.
6694 x_value *= powersOf10[y_log10 - x_log10 - 1];
6695 y_value /= 10;
6696 tie = LESS;
6697 } else if (y_log10 < x_log10) {
6698 y_value *= powersOf10[x_log10 - y_log10 - 1];
6676 x_value /= 10; 6699 x_value /= 10;
6677 } 6700 tie = GREATER;
6678 while (y_value > 0) {
6679 y_elms[y_index++] = y_value % 10;
6680 y_value /= 10;
6681 } 6701 }
6682 6702
6683 // Loop through the arrays of decimal digits finding the first place 6703 if (x_value < y_value) return Smi::FromInt(LESS);
6684 // where they differ. 6704 if (x_value > y_value) return Smi::FromInt(GREATER);
6685 while (--x_index >= 0 && --y_index >= 0) { 6705 return Smi::FromInt(tie);
6686 int diff = x_elms[x_index] - y_elms[y_index];
6687 if (diff != 0) return Smi::FromInt(diff);
6688 }
6689
6690 // If one array is a suffix of the other array, the longest array is
6691 // the representation of the largest of the Smis in the
6692 // lexicographic ordering.
6693 return Smi::FromInt(x_index - y_index);
6694 } 6706 }
6695 6707
6696 6708
6697 static Object* StringInputBufferCompare(RuntimeState* state, 6709 static Object* StringInputBufferCompare(RuntimeState* state,
6698 String* x, 6710 String* x,
6699 String* y) { 6711 String* y) {
6700 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); 6712 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx();
6701 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); 6713 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy();
6702 bufx.Reset(x); 6714 bufx.Reset(x);
6703 bufy.Reset(y); 6715 bufy.Reset(y);
(...skipping 5779 matching lines...) Expand 10 before | Expand all | Expand 10 after
12483 } else { 12495 } else {
12484 // Handle last resort GC and make sure to allow future allocations 12496 // Handle last resort GC and make sure to allow future allocations
12485 // to grow the heap without causing GCs (if possible). 12497 // to grow the heap without causing GCs (if possible).
12486 isolate->counters()->gc_last_resort_from_js()->Increment(); 12498 isolate->counters()->gc_last_resort_from_js()->Increment();
12487 isolate->heap()->CollectAllGarbage(false); 12499 isolate->heap()->CollectAllGarbage(false);
12488 } 12500 }
12489 } 12501 }
12490 12502
12491 12503
12492 } } // namespace v8::internal 12504 } } // namespace v8::internal
OLDNEW
« src/misc-intrinsics.h ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698