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

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

Powered by Google App Engine
This is Rietveld 408576698