Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
V8: remove V8_HOST_CAN_READ_UNALIGNED and its uses
Browse files Browse the repository at this point in the history
Fixes segfault in 32bit SmartOS when built with GCC 4.9.

This is the second of two backports from upstream v8:
1. v8/v8@90dc5c9
2. v8/v8@7cb82a7

Original commit message:

  Reland "Remove V8_HOST_CAN_READ_UNALIGNED and its uses."

  BUG=chromium:412967
  LOG=N
  [email protected]

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

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

V8 issue: https://code.google.com/p/chromium/issues/detail?id=412967

Fixes #25281

Reviewed-By: Julien Gilli <[email protected]>
PR-URL: #25556
  • Loading branch information
hashseed authored and joaocgreis committed Jul 1, 2015
1 parent 48b0ca2 commit 13ea50e
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 110 deletions.
4 changes: 0 additions & 4 deletions deps/v8/src/base/build_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,20 @@
// 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__) && !defined(__LP64__)
#define V8_HOST_ARCH_32_BIT 1
#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
Expand Down
10 changes: 4 additions & 6 deletions deps/v8/src/deoptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,17 @@ 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] = *reinterpret_cast<uint32_t*>(p);
c.u[1] = *reinterpret_cast<uint32_t*>(p + 4);
c.u[0] = Memory::uint32_at(p);
c.u[1] = Memory::uint32_at(p + 4);
return c.d;
#endif // V8_HOST_CAN_READ_UNALIGNED
}


Expand Down
31 changes: 1 addition & 30 deletions deps/v8/src/objects.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9026,36 +9026,7 @@ template <typename Char>
static inline bool CompareRawStringContents(const Char* const a,
const Char* const b,
int length) {
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;
return CompareChars(a, b, length) == 0;
}


Expand Down
27 changes: 19 additions & 8 deletions deps/v8/src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -9313,22 +9313,33 @@ class String: public Name {
static inline int NonAsciiStart(const char* chars, int length) {
const char* start = chars;
const char* limit = chars + length;
#ifdef V8_HOST_CAN_READ_UNALIGNED
DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
return static_cast<int>(chars - start);

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_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
return static_cast<int>(chars - start);
}
chars += sizeof(uintptr_t);
}
chars += sizeof(uintptr_t);
}
#endif
// Check remaining unaligned bytes.
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);
}

Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/regexp-macro-assembler-irregexp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ 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();
Expand Down
9 changes: 0 additions & 9 deletions deps/v8/src/regexp-macro-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,6 @@ 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)
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/regexp-macro-assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
virtual bool CanReadUnaligned() = 0;
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
Expand Down
61 changes: 32 additions & 29 deletions deps/v8/src/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6491,34 +6491,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) {
Expand All @@ -6532,9 +6536,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));
Expand Down
4 changes: 0 additions & 4 deletions deps/v8/src/snapshot-source-sink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@ 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;
}

Expand Down
25 changes: 6 additions & 19 deletions deps/v8/src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,20 +673,11 @@ 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)) {
// 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;
}
if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
// memcmp compares byte-by-byte, yielding wrong results for two-byte
// strings on little-endian systems.
return memcmp(lhs, rhs, chars);
}
#endif
while (lhs < limit) {
int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
if (r != 0) return r;
Expand Down Expand Up @@ -1350,15 +1341,11 @@ 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));
return;
}
#endif
while (dest < limit) {
*dest++ = static_cast<sinkchar>(*src++);
} else {
while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
}
}

Expand Down
7 changes: 7 additions & 0 deletions deps/v8/test/mjsunit/regress/string-compare-memcmp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax

assertEquals(-1, %StringCompare("abc\u0102", "abc\u0201"));

0 comments on commit 13ea50e

Please sign in to comment.