| Index: src/runtime/runtime-strings.cc
|
| diff --git a/src/runtime/runtime-strings.cc b/src/runtime/runtime-strings.cc
|
| index 328bdceb376c469e90c103c9464732415ba527e4..205b1898c40faa1b604d071fe63477fcf66f9669 100644
|
| --- a/src/runtime/runtime-strings.cc
|
| +++ b/src/runtime/runtime-strings.cc
|
| @@ -679,122 +679,6 @@ MUST_USE_RESULT static Object* ConvertCaseHelper(
|
| }
|
| }
|
|
|
| -
|
| -static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
|
| -static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
|
| -
|
| -// Given a word and two range boundaries returns a word with high bit
|
| -// set in every byte iff the corresponding input byte was strictly in
|
| -// the range (m, n). All the other bits in the result are cleared.
|
| -// This function is only useful when it can be inlined and the
|
| -// boundaries are statically known.
|
| -// Requires: all bytes in the input word and the boundaries must be
|
| -// ASCII (less than 0x7F).
|
| -static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
|
| - // Use strict inequalities since in edge cases the function could be
|
| - // further simplified.
|
| - DCHECK(0 < m && m < n);
|
| - // Has high bit set in every w byte less than n.
|
| - uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
|
| - // Has high bit set in every w byte greater than m.
|
| - uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
|
| - return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
|
| -}
|
| -
|
| -
|
| -#ifdef DEBUG
|
| -static bool CheckFastAsciiConvert(char* dst, const char* src, int length,
|
| - bool changed, bool is_to_lower) {
|
| - bool expected_changed = false;
|
| - for (int i = 0; i < length; i++) {
|
| - if (dst[i] == src[i]) continue;
|
| - expected_changed = true;
|
| - if (is_to_lower) {
|
| - DCHECK('A' <= src[i] && src[i] <= 'Z');
|
| - DCHECK(dst[i] == src[i] + ('a' - 'A'));
|
| - } else {
|
| - DCHECK('a' <= src[i] && src[i] <= 'z');
|
| - DCHECK(dst[i] == src[i] - ('a' - 'A'));
|
| - }
|
| - }
|
| - return (expected_changed == changed);
|
| -}
|
| -#endif
|
| -
|
| -
|
| -template <class Converter>
|
| -static bool FastAsciiConvert(char* dst, const char* src, int length,
|
| - bool* changed_out) {
|
| -#ifdef DEBUG
|
| - char* saved_dst = dst;
|
| - const char* saved_src = src;
|
| -#endif
|
| - DisallowHeapAllocation no_gc;
|
| - // We rely on the distance between upper and lower case letters
|
| - // being a known power of 2.
|
| - DCHECK('a' - 'A' == (1 << 5));
|
| - // Boundaries for the range of input characters than require conversion.
|
| - static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
|
| - static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
|
| - bool changed = false;
|
| - uintptr_t or_acc = 0;
|
| - const char* const limit = src + length;
|
| -
|
| - // dst is newly allocated and always aligned.
|
| - DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
|
| - // Only attempt processing one word at a time if src is also aligned.
|
| - if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
|
| - // Process the prefix of the input that requires no conversion one aligned
|
| - // (machine) word at a time.
|
| - while (src <= limit - sizeof(uintptr_t)) {
|
| - const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
|
| - or_acc |= w;
|
| - if (AsciiRangeMask(w, lo, hi) != 0) {
|
| - changed = true;
|
| - break;
|
| - }
|
| - *reinterpret_cast<uintptr_t*>(dst) = w;
|
| - src += sizeof(uintptr_t);
|
| - dst += sizeof(uintptr_t);
|
| - }
|
| - // Process the remainder of the input performing conversion when
|
| - // required one word at a time.
|
| - while (src <= limit - sizeof(uintptr_t)) {
|
| - const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
|
| - or_acc |= w;
|
| - uintptr_t m = AsciiRangeMask(w, lo, hi);
|
| - // The mask has high (7th) bit set in every byte that needs
|
| - // conversion and we know that the distance between cases is
|
| - // 1 << 5.
|
| - *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
|
| - src += sizeof(uintptr_t);
|
| - dst += sizeof(uintptr_t);
|
| - }
|
| - }
|
| - // Process the last few bytes of the input (or the whole input if
|
| - // unaligned access is not supported).
|
| - while (src < limit) {
|
| - char c = *src;
|
| - or_acc |= c;
|
| - if (lo < c && c < hi) {
|
| - c ^= (1 << 5);
|
| - changed = true;
|
| - }
|
| - *dst = c;
|
| - ++src;
|
| - ++dst;
|
| - }
|
| -
|
| - if ((or_acc & kAsciiMask) != 0) return false;
|
| -
|
| - DCHECK(CheckFastAsciiConvert(saved_dst, saved_src, length, changed,
|
| - Converter::kIsToLower));
|
| -
|
| - *changed_out = changed;
|
| - return true;
|
| -}
|
| -
|
| -
|
| template <class Converter>
|
| MUST_USE_RESULT static Object* ConvertCase(
|
| Handle<String> s, Isolate* isolate,
|
| @@ -818,7 +702,7 @@ MUST_USE_RESULT static Object* ConvertCase(
|
| String::FlatContent flat_content = s->GetFlatContent();
|
| DCHECK(flat_content.IsFlat());
|
| bool has_changed_character = false;
|
| - bool is_ascii = FastAsciiConvert<Converter>(
|
| + bool is_ascii = FastAsciiConvert<Converter::kIsToLower>(
|
| reinterpret_cast<char*>(result->GetChars()),
|
| reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
|
| length, &has_changed_character);
|
|
|