Revert "Remove V8_HOST_CAN_READ_UNALIGNED and its uses."
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
This commit is contained in:
parent
6b660f2812
commit
a5027daf1c
@ -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.
|
||||
@ -28,13 +29,16 @@
|
||||
#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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
21
src/utils.h
21
src/utils.h
@ -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++);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user