Commit 2da19bd4 authored by Alexander Timokhin's avatar Alexander Timokhin Committed by Commit Bot

Fix HeapNumber/MutableHeapNumber value alignment

HeapNumbers and MutableHeapNumber requires alignment for their double
value field but for now this field can be misaligned on 32-bit platforms.

According to code in Heap::GetFillToAlign() function, kDoubleUnaligned
doesn't actually mean "unaligned" but "aligned to half of double".

This CL fixes this misalignment.

Change-Id: I9b9c58d580bb287e7dad44bc96cd6b4593707b5e
Reviewed-on: https://chromium-review.googlesource.com/c/1470113
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59599}
parent a2d9924c
......@@ -426,10 +426,9 @@ AllocationResult PagedSpace::AllocateRaw(int size_in_bytes,
DCHECK_IMPLIES(!SupportsInlineAllocation(), bytes_since_last == 0);
#ifdef V8_HOST_ARCH_32_BIT
AllocationResult result =
alignment == kDoubleAligned
? AllocateRawAligned(size_in_bytes, kDoubleAligned)
: AllocateRawUnaligned(size_in_bytes);
AllocationResult result = alignment != kWordAligned
? AllocateRawAligned(size_in_bytes, alignment)
: AllocateRawUnaligned(size_in_bytes);
#else
AllocationResult result = AllocateRawUnaligned(size_in_bytes);
#endif
......@@ -512,8 +511,8 @@ AllocationResult NewSpace::AllocateRaw(int size_in_bytes,
top_on_previous_step_ = top();
}
#ifdef V8_HOST_ARCH_32_BIT
return alignment == kDoubleAligned
? AllocateRawAligned(size_in_bytes, kDoubleAligned)
return alignment != kWordAligned
? AllocateRawAligned(size_in_bytes, alignment)
: AllocateRawUnaligned(size_in_bytes);
#else
return AllocateRawUnaligned(size_in_bytes);
......
......@@ -1785,8 +1785,9 @@ static HeapObject NewSpaceAllocateAligned(int size,
static Address AlignNewSpace(AllocationAlignment alignment, int offset) {
Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
int fill = Heap::GetFillToAlign(*top_addr, alignment);
if (fill) {
NewSpaceAllocateAligned(fill + offset, kWordAligned);
int allocation = fill + offset;
if (allocation) {
NewSpaceAllocateAligned(allocation, kWordAligned);
}
return *top_addr;
}
......@@ -1908,6 +1909,64 @@ TEST(TestAlignedOverAllocation) {
}
}
TEST(HeapNumberAlignment) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope sc(isolate);
const auto required_alignment =
HeapObject::RequiredAlignment(*factory->heap_number_map());
const int maximum_misalignment =
Heap::GetMaximumFillToAlign(required_alignment);
for (int offset = 0; offset <= maximum_misalignment; offset += kTaggedSize) {
AlignNewSpace(required_alignment, offset);
Handle<Object> number_new = factory->NewNumber(1.000123);
CHECK(number_new->IsHeapNumber());
CHECK(Heap::InNewSpace(*number_new));
CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_new)->address(),
required_alignment));
AlignOldSpace(required_alignment, offset);
Handle<Object> number_old = factory->NewNumber(1.000321, TENURED);
CHECK(number_old->IsHeapNumber());
CHECK(heap->InOldSpace(*number_old));
CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_old)->address(),
required_alignment));
}
}
TEST(MutableHeapNumberAlignment) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope sc(isolate);
const auto required_alignment =
HeapObject::RequiredAlignment(*factory->mutable_heap_number_map());
const int maximum_misalignment =
Heap::GetMaximumFillToAlign(required_alignment);
for (int offset = 0; offset <= maximum_misalignment; offset += kTaggedSize) {
AlignNewSpace(required_alignment, offset);
Handle<Object> number_new = factory->NewMutableHeapNumber(1.000123);
CHECK(number_new->IsMutableHeapNumber());
CHECK(Heap::InNewSpace(*number_new));
CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_new)->address(),
required_alignment));
AlignOldSpace(required_alignment, offset);
Handle<Object> number_old =
factory->NewMutableHeapNumber(1.000321, TENURED);
CHECK(number_old->IsMutableHeapNumber());
CHECK(heap->InOldSpace(*number_old));
CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_old)->address(),
required_alignment));
}
}
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
CcTest::InitializeVM();
......
......@@ -394,7 +394,7 @@ TEST(SizeOfInitialHeap) {
#endif // DEBUG
static HeapObject AllocateUnaligned(NewSpace* space, int size) {
AllocationResult allocation = space->AllocateRawUnaligned(size);
AllocationResult allocation = space->AllocateRaw(size, kWordAligned);
CHECK(!allocation.IsRetry());
HeapObject filler;
CHECK(allocation.To(&filler));
......@@ -404,7 +404,7 @@ static HeapObject AllocateUnaligned(NewSpace* space, int size) {
}
static HeapObject AllocateUnaligned(PagedSpace* space, int size) {
AllocationResult allocation = space->AllocateRaw(size, kDoubleUnaligned);
AllocationResult allocation = space->AllocateRaw(size, kWordAligned);
CHECK(!allocation.IsRetry());
HeapObject filler;
CHECK(allocation.To(&filler));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment