Revert "Remove V8_HOST_CAN_READ_UNALIGNED and its uses."
authoryangguo@chromium.org <yangguo@chromium.org>
Fri, 12 Sep 2014 21:11:09 +0000 (21:11 +0000)
committeryangguo@chromium.org <yangguo@chromium.org>
Fri, 12 Sep 2014 21:11:09 +0000 (21:11 +0000)
This reverts r23915.

TBR=machenbach@chromium.org

Review URL: https://codereview.chromium.org/569783003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23925 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/base/build_config.h
src/deoptimizer.h
src/objects.cc
src/objects.h
src/regexp-macro-assembler-irregexp.h
src/regexp-macro-assembler.cc
src/regexp-macro-assembler.h
src/runtime.cc
src/snapshot-source-sink.cc
src/utils.h

index 2bf57c9..22b944b 100644 (file)
@@ -21,6 +21,7 @@
 // V8_HOST_ARCH_IA32 on both 32- and 64-bit x86.
 #define V8_HOST_ARCH_IA32 1
 #define V8_HOST_ARCH_32_BIT 1
+#define V8_HOST_CAN_READ_UNALIGNED 1
 #else
 #define V8_HOST_ARCH_X64 1
 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 4  // Check for x32.
 #else
 #define V8_HOST_ARCH_64_BIT 1
 #endif
+#define V8_HOST_CAN_READ_UNALIGNED 1
 #endif  // __native_client__
 #elif defined(_M_IX86) || defined(__i386__)
 #define V8_HOST_ARCH_IA32 1
 #define V8_HOST_ARCH_32_BIT 1
+#define V8_HOST_CAN_READ_UNALIGNED 1
 #elif defined(__AARCH64EL__)
 #define V8_HOST_ARCH_ARM64 1
 #define V8_HOST_ARCH_64_BIT 1
+#define V8_HOST_CAN_READ_UNALIGNED 1
 #elif defined(__ARMEL__)
 #define V8_HOST_ARCH_ARM 1
 #define V8_HOST_ARCH_32_BIT 1
index 602a21a..5d401de 100644 (file)
@@ -17,17 +17,19 @@ namespace internal {
 
 
 static inline double read_double_value(Address p) {
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+  return Memory::double_at(p);
+#else  // V8_HOST_CAN_READ_UNALIGNED
   // Prevent gcc from using load-double (mips ldc1) on (possibly)
   // non-64-bit aligned address.
-  // We assume that the address is 32-bit aligned.
-  DCHECK(IsAligned(reinterpret_cast<intptr_t>(p), kInt32Size));
   union conversion {
     double d;
     uint32_t u[2];
   } c;
-  c.u[0] = Memory::uint32_at(p);
-  c.u[1] = Memory::uint32_at(p + 4);
+  c.u[0] = *reinterpret_cast<uint32_t*>(p);
+  c.u[1] = *reinterpret_cast<uint32_t*>(p + 4);
   return c.d;
+#endif  // V8_HOST_CAN_READ_UNALIGNED
 }
 
 
index ffe724f..f73d33f 100644 (file)
@@ -8507,7 +8507,36 @@ template <typename Char>
 static inline bool CompareRawStringContents(const Char* const a,
                                             const Char* const b,
                                             int length) {
-  return CompareChars(a, b, length) == 0;
+  int i = 0;
+#ifndef V8_HOST_CAN_READ_UNALIGNED
+  // If this architecture isn't comfortable reading unaligned ints
+  // then we have to check that the strings are aligned before
+  // comparing them blockwise.
+  const int kAlignmentMask = sizeof(uint32_t) - 1;  // NOLINT
+  uintptr_t pa_addr = reinterpret_cast<uintptr_t>(a);
+  uintptr_t pb_addr = reinterpret_cast<uintptr_t>(b);
+  if (((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask)) == 0) {
+#endif
+    const int kStepSize = sizeof(int) / sizeof(Char);  // NOLINT
+    int endpoint = length - kStepSize;
+    // Compare blocks until we reach near the end of the string.
+    for (; i <= endpoint; i += kStepSize) {
+      uint32_t wa = *reinterpret_cast<const uint32_t*>(a + i);
+      uint32_t wb = *reinterpret_cast<const uint32_t*>(b + i);
+      if (wa != wb) {
+        return false;
+      }
+    }
+#ifndef V8_HOST_CAN_READ_UNALIGNED
+  }
+#endif
+  // Compare the remaining characters that didn't fit into a block.
+  for (; i < length; i++) {
+    if (a[i] != b[i]) {
+      return false;
+    }
+  }
+  return true;
 }
 
 
index 8203b36..32dd94f 100644 (file)
@@ -9172,33 +9172,22 @@ class String: public Name {
   static inline int NonAsciiStart(const char* chars, int length) {
     const char* start = chars;
     const char* limit = chars + length;
-
-    if (length >= kIntptrSize) {
-      // Check unaligned bytes.
-      while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
-        if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
-          return static_cast<int>(chars - start);
-        }
-        ++chars;
-      }
-      // Check aligned words.
-      DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
-      const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
-      while (chars + sizeof(uintptr_t) <= limit) {
-        if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
-          return static_cast<int>(chars - start);
-        }
-        chars += sizeof(uintptr_t);
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+    DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
+    const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
+    while (chars + sizeof(uintptr_t) <= limit) {
+      if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
+        return static_cast<int>(chars - start);
       }
+      chars += sizeof(uintptr_t);
     }
-    // Check remaining unaligned bytes.
+#endif
     while (chars < limit) {
       if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
         return static_cast<int>(chars - start);
       }
       ++chars;
     }
-
     return static_cast<int>(chars - start);
   }
 
index b192c22..cdfb46a 100644 (file)
@@ -31,7 +31,6 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
   virtual ~RegExpMacroAssemblerIrregexp();
   // The byte-code interpreter checks on each push anyway.
   virtual int stack_limit_slack() { return 1; }
-  virtual bool CanReadUnaligned() { return false; }
   virtual void Bind(Label* label);
   virtual void AdvanceCurrentPosition(int by);  // Signed cp change.
   virtual void PopCurrentPosition();
index 52df648..c4bfc8d 100644 (file)
@@ -24,6 +24,15 @@ RegExpMacroAssembler::~RegExpMacroAssembler() {
 }
 
 
+bool RegExpMacroAssembler::CanReadUnaligned() {
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+  return true;
+#else
+  return false;
+#endif
+}
+
+
 #ifndef V8_INTERPRETED_REGEXP  // Avoid unused code, e.g., on ARM.
 
 NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(Zone* zone)
index f72cc4d..6bb4115 100644 (file)
@@ -48,7 +48,7 @@ class RegExpMacroAssembler {
   // kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck)
   // at least once for every stack_limit() pushes that are executed.
   virtual int stack_limit_slack() = 0;
-  virtual bool CanReadUnaligned() = 0;
+  virtual bool CanReadUnaligned();
   virtual void AdvanceCurrentPosition(int by) = 0;  // Signed cp change.
   virtual void AdvanceRegister(int reg, int by) = 0;  // r[reg] += by.
   // Continues execution from the position pushed on the top of the backtrack
index 67f749b..20f3110 100644 (file)
@@ -6552,38 +6552,34 @@ static bool FastAsciiConvert(char* dst,
   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);
+#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;
     }
+    *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) {
@@ -6597,8 +6593,9 @@ 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));
index 44f8706..2be1438 100644 (file)
@@ -24,10 +24,14 @@ SnapshotByteSource::~SnapshotByteSource() { }
 
 int32_t SnapshotByteSource::GetUnalignedInt() {
   DCHECK(position_ < length_);  // Require at least one byte left.
+#if defined(V8_HOST_CAN_READ_UNALIGNED) &&  __BYTE_ORDER == __LITTLE_ENDIAN
+  int32_t answer = *reinterpret_cast<const int32_t*>(data_ + position_);
+#else
   int32_t answer = data_[position_];
   answer |= data_[position_ + 1] << 8;
   answer |= data_[position_ + 2] << 16;
   answer |= data_[position_ + 3] << 24;
+#endif
   return answer;
 }
 
index 40aff2c..07b6490 100644 (file)
@@ -680,9 +680,20 @@ inline int CompareCharsUnsigned(const lchar* lhs,
                                 const rchar* rhs,
                                 int chars) {
   const lchar* limit = lhs + chars;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
   if (sizeof(*lhs) == sizeof(*rhs)) {
-    return memcmp(lhs, rhs, sizeof(*lhs) * chars);
+    // Number of characters in a uintptr_t.
+    static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs);  // NOLINT
+    while (lhs <= limit - kStepSize) {
+      if (*reinterpret_cast<const uintptr_t*>(lhs) !=
+          *reinterpret_cast<const uintptr_t*>(rhs)) {
+        break;
+      }
+      lhs += kStepSize;
+      rhs += kStepSize;
+    }
   }
+#endif
   while (lhs < limit) {
     int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
     if (r != 0) return r;
@@ -1275,11 +1286,15 @@ void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
 template <typename sourcechar, typename sinkchar>
 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
   sinkchar* limit = dest + chars;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
   if ((sizeof(*dest) == sizeof(*src)) &&
       (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest)))) {
     MemCopy(dest, src, chars * sizeof(*dest));
-  } else {
-    while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
+    return;
+  }
+#endif
+  while (dest < limit) {
+    *dest++ = static_cast<sinkchar>(*src++);
   }
 }