Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 20f311089b7c8ddc59e0276828b03fa3ea64454c..67f749b27024fd7df478934a5a3acf492f43a4bc 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -6552,34 +6552,38 @@ 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; |
+ |
+ // 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); |
} |
- *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 +6597,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)); |