OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |