Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index f0c1d95f88275bc3b5a6af003d149d27ffa51c12..b982bfd1000aeb7048f75073d67b7c28cb9f19de 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -6552,34 +6552,50 @@ static bool FastAsciiConvert(char* dst, |
| bool changed = false; |
| uintptr_t or_acc = 0; |
| const char* const limit = src + length; |
| -#ifdef V8_HOST_CAN_READ_UNALIGNED |
| - // Process the prefix of the input that requires no conversion one |
| - // (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; |
| + |
| + if (length >= kIntptrSize) { |
| + // Process the prefix of the input that requires no conversion one |
| + // unaligned byte at a time. |
| + while (!IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) { |
| + char c = *src; |
| + or_acc |= c; |
| + if (lo < c && c < hi) { |
| + c ^= (1 << 5); |
| + changed = true; |
| + } |
| + *dst = c; |
| + ++src; |
| + ++dst; |
| + } |
| + // Process the prefix of the input that requires no conversion one aligned |
| + // (machine) word at a time. |
| + if (!changed) { |
| + 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; |
|
Jakob Kummerow
2014/09/12 11:08:44
Who guarantees that dst is aligned here?
|
| + 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); |
| } |
| - *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); |
| } |
| -#endif |
| // Process the last few bytes of the input (or the whole input if |
| // unaligned access is not supported). |
| while (src < limit) { |
| @@ -6593,9 +6609,8 @@ static bool FastAsciiConvert(char* dst, |
| ++src; |
| ++dst; |
| } |
| - if ((or_acc & kAsciiMask) != 0) { |
| - return false; |
| - } |
| + |
| + if ((or_acc & kAsciiMask) != 0) return false; |
| DCHECK(CheckFastAsciiConvert( |
| saved_dst, saved_src, length, changed, Converter::kIsToLower)); |