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,9 +426,8 @@ AllocationResult PagedSpace::AllocateRaw(int size_in_bytes, ...@@ -426,9 +426,8 @@ AllocationResult PagedSpace::AllocateRaw(int size_in_bytes,
DCHECK_IMPLIES(!SupportsInlineAllocation(), bytes_since_last == 0); DCHECK_IMPLIES(!SupportsInlineAllocation(), bytes_since_last == 0);
#ifdef V8_HOST_ARCH_32_BIT #ifdef V8_HOST_ARCH_32_BIT
AllocationResult result = AllocationResult result = alignment != kWordAligned
alignment == kDoubleAligned ? AllocateRawAligned(size_in_bytes, alignment)
? AllocateRawAligned(size_in_bytes, kDoubleAligned)
: AllocateRawUnaligned(size_in_bytes); : AllocateRawUnaligned(size_in_bytes);
#else #else
AllocationResult result = AllocateRawUnaligned(size_in_bytes); AllocationResult result = AllocateRawUnaligned(size_in_bytes);
...@@ -512,8 +511,8 @@ AllocationResult NewSpace::AllocateRaw(int size_in_bytes, ...@@ -512,8 +511,8 @@ AllocationResult NewSpace::AllocateRaw(int size_in_bytes,
top_on_previous_step_ = top(); top_on_previous_step_ = top();
} }
#ifdef V8_HOST_ARCH_32_BIT #ifdef V8_HOST_ARCH_32_BIT
return alignment == kDoubleAligned return alignment != kWordAligned
? AllocateRawAligned(size_in_bytes, kDoubleAligned) ? AllocateRawAligned(size_in_bytes, alignment)
: AllocateRawUnaligned(size_in_bytes); : AllocateRawUnaligned(size_in_bytes);
#else #else
return AllocateRawUnaligned(size_in_bytes); return AllocateRawUnaligned(size_in_bytes);
......
...@@ -1785,8 +1785,9 @@ static HeapObject NewSpaceAllocateAligned(int size, ...@@ -1785,8 +1785,9 @@ static HeapObject NewSpaceAllocateAligned(int size,
static Address AlignNewSpace(AllocationAlignment alignment, int offset) { static Address AlignNewSpace(AllocationAlignment alignment, int offset) {
Address* top_addr = CcTest::heap()->new_space()->allocation_top_address(); Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
int fill = Heap::GetFillToAlign(*top_addr, alignment); int fill = Heap::GetFillToAlign(*top_addr, alignment);
if (fill) { int allocation = fill + offset;
NewSpaceAllocateAligned(fill + offset, kWordAligned); if (allocation) {
NewSpaceAllocateAligned(allocation, kWordAligned);
} }
return *top_addr; return *top_addr;
} }
...@@ -1908,6 +1909,64 @@ TEST(TestAlignedOverAllocation) { ...@@ -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) { TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
CcTest::InitializeVM(); CcTest::InitializeVM();
......
...@@ -394,7 +394,7 @@ TEST(SizeOfInitialHeap) { ...@@ -394,7 +394,7 @@ TEST(SizeOfInitialHeap) {
#endif // DEBUG #endif // DEBUG
static HeapObject AllocateUnaligned(NewSpace* space, int size) { static HeapObject AllocateUnaligned(NewSpace* space, int size) {
AllocationResult allocation = space->AllocateRawUnaligned(size); AllocationResult allocation = space->AllocateRaw(size, kWordAligned);
CHECK(!allocation.IsRetry()); CHECK(!allocation.IsRetry());
HeapObject filler; HeapObject filler;
CHECK(allocation.To(&filler)); CHECK(allocation.To(&filler));
...@@ -404,7 +404,7 @@ static HeapObject AllocateUnaligned(NewSpace* space, int size) { ...@@ -404,7 +404,7 @@ static HeapObject AllocateUnaligned(NewSpace* space, int size) {
} }
static HeapObject AllocateUnaligned(PagedSpace* 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()); CHECK(!allocation.IsRetry());
HeapObject filler; HeapObject filler;
CHECK(allocation.To(&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