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

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, 5 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 | « src/runtime.h ('k') | test/mjsunit/array-sort.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 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 6580 matching lines...) Expand 10 before | Expand all | Expand 10 after
6638 6639
6639 // Extract the integer values from the Smis. 6640 // Extract the integer values from the Smis.
6640 CONVERT_CHECKED(Smi, x, args[0]); 6641 CONVERT_CHECKED(Smi, x, args[0]);
6641 CONVERT_CHECKED(Smi, y, args[1]); 6642 CONVERT_CHECKED(Smi, y, args[1]);
6642 int x_value = x->value(); 6643 int x_value = x->value();
6643 int y_value = y->value(); 6644 int y_value = y->value();
6644 6645
6645 // If the integers are equal so are the string representations. 6646 // If the integers are equal so are the string representations.
6646 if (x_value == y_value) return Smi::FromInt(EQUAL); 6647 if (x_value == y_value) return Smi::FromInt(EQUAL);
6647 6648
6648 // If one of the integers are zero the normal integer order is the 6649 // If one of the integers is zero the normal integer order is the
6649 // same as the lexicographic order of the string representations. 6650 // same as the lexicographic order of the string representations.
6650 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); 6651 if (x_value == 0 || y_value == 0)
6652 return Smi::FromInt(x_value < y_value ? LESS : GREATER);
6651 6653
6652 // If only one of the integers is negative the negative number is 6654 // If only one of the integers is negative the negative number is
6653 // smallest because the char code of '-' is less than the char code 6655 // smallest because the char code of '-' is less than the char code
6654 // of any digit. Otherwise, we make both values positive. 6656 // of any digit. Otherwise, we make both values positive.
6657
6658 // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
6659 // architectures using 32-bit Smis.
6660 uint32_t x_scaled = x_value;
6661 uint32_t y_scaled = y_value;
6655 if (x_value < 0 || y_value < 0) { 6662 if (x_value < 0 || y_value < 0) {
6656 if (y_value >= 0) return Smi::FromInt(LESS); 6663 if (y_value >= 0) return Smi::FromInt(LESS);
6657 if (x_value >= 0) return Smi::FromInt(GREATER); 6664 if (x_value >= 0) return Smi::FromInt(GREATER);
6658 x_value = -x_value; 6665 x_scaled = -x_value;
6659 y_value = -y_value; 6666 y_scaled = -y_value;
6660 } 6667 }
6661 6668
6662 // Arrays for the individual characters of the two Smis. Smis are 6669 static const uint32_t kPowersOf10[] = {
6663 // 31 bit integers and 10 decimal digits are therefore enough. 6670 1, 10, 100, 1000, 10*1000, 100*1000,
6664 // TODO(isolates): maybe we should simply allocate 20 bytes on the stack. 6671 1000*1000, 10*1000*1000, 100*1000*1000,
6665 int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms(); 6672 1000*1000*1000
6666 int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms(); 6673 };
6667 6674
6675 // If the integers have the same number of decimal digits they can be
6676 // compared directly as the numeric order is the same as the
6677 // lexicographic order. If one integer has fewer digits, it is scaled
6678 // by some power of 10 to have the same number of digits as the longer
6679 // integer. If the scaled integers are equal it means the shorter
6680 // integer comes first in the lexicographic order.
6668 6681
6669 // Convert the integers to arrays of their decimal digits. 6682 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6670 int x_index = 0; 6683 int x_log2 = IntegerLog2(x_scaled);
6671 int y_index = 0; 6684 int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6672 while (x_value > 0) { 6685 x_log10 -= x_scaled < kPowersOf10[x_log10];
6673 x_elms[x_index++] = x_value % 10; 6686
6674 x_value /= 10; 6687 int y_log2 = IntegerLog2(y_scaled);
6675 } 6688 int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6676 while (y_value > 0) { 6689 y_log10 -= y_scaled < kPowersOf10[y_log10];
6677 y_elms[y_index++] = y_value % 10; 6690
6678 y_value /= 10; 6691 int tie = EQUAL;
6692
6693 if (x_log10 < y_log10) {
6694 // X has fewer digits. We would like to simply scale up X but that
6695 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6696 // be scaled up to 9_000_000_000. So we scale up by the next
6697 // smallest power and scale down Y to drop one digit. It is OK to
6698 // drop one digit from the longer integer since the final digit is
6699 // past the length of the shorter integer.
6700 x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
6701 y_scaled /= 10;
6702 tie = LESS;
6703 } else if (y_log10 < x_log10) {
6704 y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
6705 x_scaled /= 10;
6706 tie = GREATER;
6679 } 6707 }
6680 6708
6681 // Loop through the arrays of decimal digits finding the first place 6709 if (x_scaled < y_scaled) return Smi::FromInt(LESS);
6682 // where they differ. 6710 if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
6683 while (--x_index >= 0 && --y_index >= 0) { 6711 return Smi::FromInt(tie);
6684 int diff = x_elms[x_index] - y_elms[y_index];
6685 if (diff != 0) return Smi::FromInt(diff);
6686 }
6687
6688 // If one array is a suffix of the other array, the longest array is
6689 // the representation of the largest of the Smis in the
6690 // lexicographic ordering.
6691 return Smi::FromInt(x_index - y_index);
6692 } 6712 }
6693 6713
6694 6714
6695 static Object* StringInputBufferCompare(RuntimeState* state, 6715 static Object* StringInputBufferCompare(RuntimeState* state,
6696 String* x, 6716 String* x,
6697 String* y) { 6717 String* y) {
6698 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); 6718 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx();
6699 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); 6719 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy();
6700 bufx.Reset(x); 6720 bufx.Reset(x);
6701 bufy.Reset(y); 6721 bufy.Reset(y);
(...skipping 5779 matching lines...) Expand 10 before | Expand all | Expand 10 after
12481 } else { 12501 } else {
12482 // Handle last resort GC and make sure to allow future allocations 12502 // Handle last resort GC and make sure to allow future allocations
12483 // to grow the heap without causing GCs (if possible). 12503 // to grow the heap without causing GCs (if possible).
12484 isolate->counters()->gc_last_resort_from_js()->Increment(); 12504 isolate->counters()->gc_last_resort_from_js()->Increment();
12485 isolate->heap()->CollectAllGarbage(false); 12505 isolate->heap()->CollectAllGarbage(false);
12486 } 12506 }
12487 } 12507 }
12488 12508
12489 12509
12490 } } // namespace v8::internal 12510 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/array-sort.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698