| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index ed1e26525aa9a75dfb1f0d3e1731020c607c179f..3c1a003809bbb4efd0021c1bc8c45e5144b5a051 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -4315,17 +4315,49 @@ class ContainsOnlyOneByteHelper {
|
| void VisitOneByteString(const uint8_t* chars, int length) {
|
| // Nothing to do.
|
| }
|
| - // TODO(dcarney): do word aligned read.
|
| void VisitTwoByteString(const uint16_t* chars, int length) {
|
| - // Check whole string without breaking.
|
| - uint16_t total = 0;
|
| - for (int i = 0; i < length; i++) {
|
| - total |= chars[i] >> 8;
|
| + // Accumulated bits.
|
| + uintptr_t acc = 0;
|
| + // Align to uintptr_t.
|
| + const uint16_t* end = chars + length;
|
| + while (Unaligned(chars) && chars != end) {
|
| + acc |= *chars++;
|
| }
|
| - if (total != 0) is_one_byte_ = false;
|
| + // Read word aligned in blocks,
|
| + // checking the return value at the end of each block.
|
| + const uint16_t* aligned_end = Align(end);
|
| + const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
|
| + const int inner_loops = 16;
|
| + while (chars + inner_loops*increment < aligned_end) {
|
| + for (int i = 0; i < inner_loops; i++) {
|
| + acc |= *reinterpret_cast<const uintptr_t*>(chars);
|
| + chars += increment;
|
| + }
|
| + // Check for early return.
|
| + if ((acc & kOneByteMask) != 0) {
|
| + is_one_byte_ = false;
|
| + return;
|
| + }
|
| + }
|
| + // Read the rest.
|
| + while (chars != end) {
|
| + acc |= *chars++;
|
| + }
|
| + // Check result.
|
| + if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
|
| }
|
|
|
| private:
|
| + static const uintptr_t kOneByteMask =
|
| + static_cast<uintptr_t>(0xFF00FF00FF00FF00ULL);
|
| + static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
|
| + static inline bool Unaligned(const uint16_t* chars) {
|
| + return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
|
| + }
|
| + static inline const uint16_t* Align(const uint16_t* chars) {
|
| + return reinterpret_cast<uint16_t*>(
|
| + reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
|
| + }
|
| bool CheckCons(i::ConsString* cons_string) {
|
| while (true) {
|
| // Check left side if flat.
|
|
|