Chromium Code Reviews| 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 6582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |