Skip to content
This repository was archived by the owner on Oct 16, 2021. It is now read-only.

Commit c4b8e44

Browse files
hashseedjBarz
authored andcommitted
V8: remove V8_HOST_CAN_READ_UNALIGNED and its uses
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 R=jkummerow@chromium.org 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 nodejs#25281 Reviewed-By: Julien Gilli <julien.gilli@joyent.com> PR-URL: nodejs#25556
1 parent 7c3b82d commit c4b8e44

11 files changed

+71
-110
lines changed

deps/v8/src/base/build_config.h

-4
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,20 @@
2121
// V8_HOST_ARCH_IA32 on both 32- and 64-bit x86.
2222
#define V8_HOST_ARCH_IA32 1
2323
#define V8_HOST_ARCH_32_BIT 1
24-
#define V8_HOST_CAN_READ_UNALIGNED 1
2524
#else
2625
#define V8_HOST_ARCH_X64 1
2726
#if defined(__x86_64__) && !defined(__LP64__)
2827
#define V8_HOST_ARCH_32_BIT 1
2928
#else
3029
#define V8_HOST_ARCH_64_BIT 1
3130
#endif
32-
#define V8_HOST_CAN_READ_UNALIGNED 1
3331
#endif // __native_client__
3432
#elif defined(_M_IX86) || defined(__i386__)
3533
#define V8_HOST_ARCH_IA32 1
3634
#define V8_HOST_ARCH_32_BIT 1
37-
#define V8_HOST_CAN_READ_UNALIGNED 1
3835
#elif defined(__AARCH64EL__)
3936
#define V8_HOST_ARCH_ARM64 1
4037
#define V8_HOST_ARCH_64_BIT 1
41-
#define V8_HOST_CAN_READ_UNALIGNED 1
4238
#elif defined(__ARMEL__)
4339
#define V8_HOST_ARCH_ARM 1
4440
#define V8_HOST_ARCH_32_BIT 1

deps/v8/src/deoptimizer.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,17 @@ namespace internal {
1717

1818

1919
static inline double read_double_value(Address p) {
20-
#ifdef V8_HOST_CAN_READ_UNALIGNED
21-
return Memory::double_at(p);
22-
#else // V8_HOST_CAN_READ_UNALIGNED
2320
// Prevent gcc from using load-double (mips ldc1) on (possibly)
2421
// non-64-bit aligned address.
22+
// We assume that the address is 32-bit aligned.
23+
DCHECK(IsAligned(reinterpret_cast<intptr_t>(p), kInt32Size));
2524
union conversion {
2625
double d;
2726
uint32_t u[2];
2827
} c;
29-
c.u[0] = *reinterpret_cast<uint32_t*>(p);
30-
c.u[1] = *reinterpret_cast<uint32_t*>(p + 4);
28+
c.u[0] = Memory::uint32_at(p);
29+
c.u[1] = Memory::uint32_at(p + 4);
3130
return c.d;
32-
#endif // V8_HOST_CAN_READ_UNALIGNED
3331
}
3432

3533

deps/v8/src/objects.cc

+1-30
Original file line numberDiff line numberDiff line change
@@ -9026,36 +9026,7 @@ template <typename Char>
90269026
static inline bool CompareRawStringContents(const Char* const a,
90279027
const Char* const b,
90289028
int length) {
9029-
int i = 0;
9030-
#ifndef V8_HOST_CAN_READ_UNALIGNED
9031-
// If this architecture isn't comfortable reading unaligned ints
9032-
// then we have to check that the strings are aligned before
9033-
// comparing them blockwise.
9034-
const int kAlignmentMask = sizeof(uint32_t) - 1; // NOLINT
9035-
uintptr_t pa_addr = reinterpret_cast<uintptr_t>(a);
9036-
uintptr_t pb_addr = reinterpret_cast<uintptr_t>(b);
9037-
if (((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask)) == 0) {
9038-
#endif
9039-
const int kStepSize = sizeof(int) / sizeof(Char); // NOLINT
9040-
int endpoint = length - kStepSize;
9041-
// Compare blocks until we reach near the end of the string.
9042-
for (; i <= endpoint; i += kStepSize) {
9043-
uint32_t wa = *reinterpret_cast<const uint32_t*>(a + i);
9044-
uint32_t wb = *reinterpret_cast<const uint32_t*>(b + i);
9045-
if (wa != wb) {
9046-
return false;
9047-
}
9048-
}
9049-
#ifndef V8_HOST_CAN_READ_UNALIGNED
9050-
}
9051-
#endif
9052-
// Compare the remaining characters that didn't fit into a block.
9053-
for (; i < length; i++) {
9054-
if (a[i] != b[i]) {
9055-
return false;
9056-
}
9057-
}
9058-
return true;
9029+
return CompareChars(a, b, length) == 0;
90599030
}
90609031

90619032

deps/v8/src/objects.h

+19-8
Original file line numberDiff line numberDiff line change
@@ -9313,22 +9313,33 @@ class String: public Name {
93139313
static inline int NonAsciiStart(const char* chars, int length) {
93149314
const char* start = chars;
93159315
const char* limit = chars + length;
9316-
#ifdef V8_HOST_CAN_READ_UNALIGNED
9317-
DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9318-
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9319-
while (chars + sizeof(uintptr_t) <= limit) {
9320-
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
9321-
return static_cast<int>(chars - start);
9316+
9317+
if (length >= kIntptrSize) {
9318+
// Check unaligned bytes.
9319+
while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
9320+
if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9321+
return static_cast<int>(chars - start);
9322+
}
9323+
++chars;
9324+
}
9325+
// Check aligned words.
9326+
DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9327+
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9328+
while (chars + sizeof(uintptr_t) <= limit) {
9329+
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
9330+
return static_cast<int>(chars - start);
9331+
}
9332+
chars += sizeof(uintptr_t);
93229333
}
9323-
chars += sizeof(uintptr_t);
93249334
}
9325-
#endif
9335+
// Check remaining unaligned bytes.
93269336
while (chars < limit) {
93279337
if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
93289338
return static_cast<int>(chars - start);
93299339
}
93309340
++chars;
93319341
}
9342+
93329343
return static_cast<int>(chars - start);
93339344
}
93349345

deps/v8/src/regexp-macro-assembler-irregexp.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
3131
virtual ~RegExpMacroAssemblerIrregexp();
3232
// The byte-code interpreter checks on each push anyway.
3333
virtual int stack_limit_slack() { return 1; }
34+
virtual bool CanReadUnaligned() { return false; }
3435
virtual void Bind(Label* label);
3536
virtual void AdvanceCurrentPosition(int by); // Signed cp change.
3637
virtual void PopCurrentPosition();

deps/v8/src/regexp-macro-assembler.cc

-9
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,6 @@ RegExpMacroAssembler::~RegExpMacroAssembler() {
2424
}
2525

2626

27-
bool RegExpMacroAssembler::CanReadUnaligned() {
28-
#ifdef V8_HOST_CAN_READ_UNALIGNED
29-
return true;
30-
#else
31-
return false;
32-
#endif
33-
}
34-
35-
3627
#ifndef V8_INTERPRETED_REGEXP // Avoid unused code, e.g., on ARM.
3728

3829
NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(Zone* zone)

deps/v8/src/regexp-macro-assembler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class RegExpMacroAssembler {
4848
// kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck)
4949
// at least once for every stack_limit() pushes that are executed.
5050
virtual int stack_limit_slack() = 0;
51-
virtual bool CanReadUnaligned();
51+
virtual bool CanReadUnaligned() = 0;
5252
virtual void AdvanceCurrentPosition(int by) = 0; // Signed cp change.
5353
virtual void AdvanceRegister(int reg, int by) = 0; // r[reg] += by.
5454
// Continues execution from the position pushed on the top of the backtrack

deps/v8/src/runtime.cc

+32-29
Original file line numberDiff line numberDiff line change
@@ -6491,34 +6491,38 @@ static bool FastAsciiConvert(char* dst,
64916491
bool changed = false;
64926492
uintptr_t or_acc = 0;
64936493
const char* const limit = src + length;
6494-
#ifdef V8_HOST_CAN_READ_UNALIGNED
6495-
// Process the prefix of the input that requires no conversion one
6496-
// (machine) word at a time.
6497-
while (src <= limit - sizeof(uintptr_t)) {
6498-
const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6499-
or_acc |= w;
6500-
if (AsciiRangeMask(w, lo, hi) != 0) {
6501-
changed = true;
6502-
break;
6494+
6495+
// dst is newly allocated and always aligned.
6496+
DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
6497+
// Only attempt processing one word at a time if src is also aligned.
6498+
if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
6499+
// Process the prefix of the input that requires no conversion one aligned
6500+
// (machine) word at a time.
6501+
while (src <= limit - sizeof(uintptr_t)) {
6502+
const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6503+
or_acc |= w;
6504+
if (AsciiRangeMask(w, lo, hi) != 0) {
6505+
changed = true;
6506+
break;
6507+
}
6508+
*reinterpret_cast<uintptr_t*>(dst) = w;
6509+
src += sizeof(uintptr_t);
6510+
dst += sizeof(uintptr_t);
6511+
}
6512+
// Process the remainder of the input performing conversion when
6513+
// required one word at a time.
6514+
while (src <= limit - sizeof(uintptr_t)) {
6515+
const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6516+
or_acc |= w;
6517+
uintptr_t m = AsciiRangeMask(w, lo, hi);
6518+
// The mask has high (7th) bit set in every byte that needs
6519+
// conversion and we know that the distance between cases is
6520+
// 1 << 5.
6521+
*reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6522+
src += sizeof(uintptr_t);
6523+
dst += sizeof(uintptr_t);
65036524
}
6504-
*reinterpret_cast<uintptr_t*>(dst) = w;
6505-
src += sizeof(uintptr_t);
6506-
dst += sizeof(uintptr_t);
6507-
}
6508-
// Process the remainder of the input performing conversion when
6509-
// required one word at a time.
6510-
while (src <= limit - sizeof(uintptr_t)) {
6511-
const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6512-
or_acc |= w;
6513-
uintptr_t m = AsciiRangeMask(w, lo, hi);
6514-
// The mask has high (7th) bit set in every byte that needs
6515-
// conversion and we know that the distance between cases is
6516-
// 1 << 5.
6517-
*reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6518-
src += sizeof(uintptr_t);
6519-
dst += sizeof(uintptr_t);
65206525
}
6521-
#endif
65226526
// Process the last few bytes of the input (or the whole input if
65236527
// unaligned access is not supported).
65246528
while (src < limit) {
@@ -6532,9 +6536,8 @@ static bool FastAsciiConvert(char* dst,
65326536
++src;
65336537
++dst;
65346538
}
6535-
if ((or_acc & kAsciiMask) != 0) {
6536-
return false;
6537-
}
6539+
6540+
if ((or_acc & kAsciiMask) != 0) return false;
65386541

65396542
DCHECK(CheckFastAsciiConvert(
65406543
saved_dst, saved_src, length, changed, Converter::kIsToLower));

deps/v8/src/snapshot-source-sink.cc

-4
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,10 @@ SnapshotByteSource::~SnapshotByteSource() { }
2424

2525
int32_t SnapshotByteSource::GetUnalignedInt() {
2626
DCHECK(position_ < length_); // Require at least one byte left.
27-
#if defined(V8_HOST_CAN_READ_UNALIGNED) && __BYTE_ORDER == __LITTLE_ENDIAN
28-
int32_t answer = *reinterpret_cast<const int32_t*>(data_ + position_);
29-
#else
3027
int32_t answer = data_[position_];
3128
answer |= data_[position_ + 1] << 8;
3229
answer |= data_[position_ + 2] << 16;
3330
answer |= data_[position_ + 3] << 24;
34-
#endif
3531
return answer;
3632
}
3733

deps/v8/src/utils.h

+6-19
Original file line numberDiff line numberDiff line change
@@ -673,20 +673,11 @@ inline int CompareCharsUnsigned(const lchar* lhs,
673673
const rchar* rhs,
674674
int chars) {
675675
const lchar* limit = lhs + chars;
676-
#ifdef V8_HOST_CAN_READ_UNALIGNED
677-
if (sizeof(*lhs) == sizeof(*rhs)) {
678-
// Number of characters in a uintptr_t.
679-
static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs); // NOLINT
680-
while (lhs <= limit - kStepSize) {
681-
if (*reinterpret_cast<const uintptr_t*>(lhs) !=
682-
*reinterpret_cast<const uintptr_t*>(rhs)) {
683-
break;
684-
}
685-
lhs += kStepSize;
686-
rhs += kStepSize;
687-
}
676+
if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
677+
// memcmp compares byte-by-byte, yielding wrong results for two-byte
678+
// strings on little-endian systems.
679+
return memcmp(lhs, rhs, chars);
688680
}
689-
#endif
690681
while (lhs < limit) {
691682
int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
692683
if (r != 0) return r;
@@ -1350,15 +1341,11 @@ void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
13501341
template <typename sourcechar, typename sinkchar>
13511342
void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
13521343
sinkchar* limit = dest + chars;
1353-
#ifdef V8_HOST_CAN_READ_UNALIGNED
13541344
if ((sizeof(*dest) == sizeof(*src)) &&
13551345
(chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest)))) {
13561346
MemCopy(dest, src, chars * sizeof(*dest));
1357-
return;
1358-
}
1359-
#endif
1360-
while (dest < limit) {
1361-
*dest++ = static_cast<sinkchar>(*src++);
1347+
} else {
1348+
while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
13621349
}
13631350
}
13641351

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2012 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --allow-natives-syntax
6+
7+
assertEquals(-1, %StringCompare("abc\u0102", "abc\u0201"));

0 commit comments

Comments
 (0)