e639eafea3
This is a reland of352b9ecbdb
The test/fix CL has been merged in, as the fixes to return slot accounting are needed to fix Arm64 issues turned up by the fuzzers: https://chromium-review.googlesource.com/c/v8/v8/+/2644139 The reverted fix for Wasm return slot allocation is added in patchset #2, to avoid fuzzer issues that it fixed: https://chromium-review.googlesource.com/c/v8/v8/+/2683024 TBR=neis@chromium.org Original change's description: > Reland "Reland "[compiler][wasm] Align Frame slots to value size"" > > This is a reland of1694925c72
> > Minor fix to linkage for constexpr. > > TBR=ahaas@chromium.org,neis@chromium.org > > Original change's description: > > Reland "[compiler][wasm] Align Frame slots to value size" > > > > This is a reland ofcddaf66c37
> > > > Original change's description: > > > [compiler][wasm] Align Frame slots to value size > > > > > > - Adds an AlignedSlotAllocator class and tests, to unify slot > > > allocation. This attempts to use alignment holes for smaller > > > values. > > > - Reworks Frame to use the new allocator for stack slots. > > > - Reworks LinkageAllocator to use the new allocator for stack > > > slots and for ARMv7 FP register aliasing. > > > - Fixes the RegisterAllocator to align spill slots. > > > - Fixes InstructionSelector to align spill slots. > > > > > > Bug: v8:9198 > > > > > > Change-Id: Ida148db428be89ef95de748ec5fc0e7b0358f523 > > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2512840 > > > Commit-Queue: Bill Budge <bbudge@chromium.org> > > > Reviewed-by: Georg Neis <neis@chromium.org> > > > Reviewed-by: Andreas Haas <ahaas@chromium.org> > > > Cr-Commit-Position: refs/heads/master@{#71644} > > > > Bug: v8:9198 > > Change-Id: Ib91fa6746370c38496706341e12d05c7bf999389 > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2633390 > > Commit-Queue: Bill Budge <bbudge@chromium.org> > > Reviewed-by: Andreas Haas <ahaas@chromium.org> > > Reviewed-by: Georg Neis <neis@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#72195} > > Bug: v8:9198 > Change-Id: I91e02b823af8ec925dacf075388fb22e3eeb3384 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2640890 > Reviewed-by: Bill Budge <bbudge@chromium.org> > Commit-Queue: Bill Budge <bbudge@chromium.org> > Cr-Commit-Position: refs/heads/master@{#72209} Bug: v8:9198 Change-Id: Ia5cf63af4e5991bc7cf42da9972ffd044fc829f0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2733177 Commit-Queue: Bill Budge <bbudge@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#73238}
176 lines
5.0 KiB
C++
176 lines
5.0 KiB
C++
// Copyright 2020 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.
|
|
|
|
#include "src/codegen/aligned-slot-allocator.h"
|
|
|
|
#include "src/base/bits.h"
|
|
#include "testing/gtest-support.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
class AlignedSlotAllocatorUnitTest : public ::testing::Test {
|
|
public:
|
|
AlignedSlotAllocatorUnitTest() = default;
|
|
~AlignedSlotAllocatorUnitTest() override = default;
|
|
|
|
// Helper method to test AlignedSlotAllocator::Allocate.
|
|
void Allocate(int size, int expected) {
|
|
int next = allocator_.NextSlot(size);
|
|
int result = allocator_.Allocate(size);
|
|
EXPECT_EQ(next, result); // NextSlot/Allocate are consistent.
|
|
EXPECT_EQ(expected, result);
|
|
EXPECT_EQ(0, result & (size - 1)); // result is aligned to size.
|
|
int slot_end = result + static_cast<int>(base::bits::RoundUpToPowerOfTwo32(
|
|
static_cast<uint32_t>(size)));
|
|
EXPECT_LE(slot_end, allocator_.Size()); // allocator Size is beyond slot.
|
|
}
|
|
|
|
// Helper method to test AlignedSlotAllocator::AllocateUnaligned.
|
|
void AllocateUnaligned(int size, int expected, int expected1, int expected2,
|
|
int expected4) {
|
|
int size_before = allocator_.Size();
|
|
int result = allocator_.AllocateUnaligned(size);
|
|
EXPECT_EQ(size_before, result); // AllocateUnaligned/Size are consistent.
|
|
EXPECT_EQ(expected, result);
|
|
EXPECT_EQ(result + size, allocator_.Size());
|
|
EXPECT_EQ(expected1, allocator_.NextSlot(1));
|
|
EXPECT_EQ(expected2, allocator_.NextSlot(2));
|
|
EXPECT_EQ(expected4, allocator_.NextSlot(4));
|
|
}
|
|
|
|
AlignedSlotAllocator allocator_;
|
|
};
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, NumSlotsForWidth) {
|
|
constexpr int kSlotBytes = AlignedSlotAllocator::kSlotSize;
|
|
for (int slot_size = 1; slot_size <= 4 * kSlotBytes; ++slot_size) {
|
|
EXPECT_EQ(AlignedSlotAllocator::NumSlotsForWidth(slot_size),
|
|
(slot_size + kSlotBytes - 1) / kSlotBytes);
|
|
}
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, Allocate1) {
|
|
Allocate(1, 0);
|
|
EXPECT_EQ(2, allocator_.NextSlot(2));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
Allocate(1, 1);
|
|
EXPECT_EQ(2, allocator_.NextSlot(2));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
Allocate(1, 2);
|
|
EXPECT_EQ(4, allocator_.NextSlot(2));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
Allocate(1, 3);
|
|
EXPECT_EQ(4, allocator_.NextSlot(2));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
// Make sure we use 1-fragments.
|
|
Allocate(1, 4);
|
|
Allocate(2, 6);
|
|
Allocate(1, 5);
|
|
|
|
// Make sure we use 2-fragments.
|
|
Allocate(2, 8);
|
|
Allocate(1, 10);
|
|
Allocate(1, 11);
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, Allocate2) {
|
|
Allocate(2, 0);
|
|
EXPECT_EQ(2, allocator_.NextSlot(1));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
Allocate(2, 2);
|
|
EXPECT_EQ(4, allocator_.NextSlot(1));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
|
|
// Make sure we use 2-fragments.
|
|
Allocate(1, 4);
|
|
Allocate(2, 6);
|
|
Allocate(2, 8);
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, Allocate4) {
|
|
Allocate(4, 0);
|
|
EXPECT_EQ(4, allocator_.NextSlot(1));
|
|
EXPECT_EQ(4, allocator_.NextSlot(2));
|
|
|
|
Allocate(1, 4);
|
|
Allocate(4, 8);
|
|
|
|
Allocate(2, 6);
|
|
Allocate(4, 12);
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, AllocateUnaligned) {
|
|
AllocateUnaligned(1, 0, 1, 2, 4);
|
|
AllocateUnaligned(1, 1, 2, 2, 4);
|
|
|
|
Allocate(1, 2);
|
|
|
|
AllocateUnaligned(2, 3, 5, 6, 8);
|
|
|
|
// Advance to leave 1- and 2- fragments below Size.
|
|
Allocate(4, 8);
|
|
|
|
// AllocateUnaligned should allocate at the end, and clear fragments.
|
|
AllocateUnaligned(0, 12, 12, 12, 12);
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, LargeAllocateUnaligned) {
|
|
AllocateUnaligned(11, 0, 11, 12, 12);
|
|
AllocateUnaligned(11, 11, 22, 22, 24);
|
|
AllocateUnaligned(13, 22, 35, 36, 36);
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, Size) {
|
|
allocator_.Allocate(1);
|
|
EXPECT_EQ(1, allocator_.Size());
|
|
// Allocate 2, leaving a fragment at 1. Size should be at 4.
|
|
allocator_.Allocate(2);
|
|
EXPECT_EQ(4, allocator_.Size());
|
|
// Allocate should consume fragment.
|
|
EXPECT_EQ(1, allocator_.Allocate(1));
|
|
// Size should still be 4.
|
|
EXPECT_EQ(4, allocator_.Size());
|
|
}
|
|
|
|
TEST_F(AlignedSlotAllocatorUnitTest, Align) {
|
|
EXPECT_EQ(0, allocator_.Align(1));
|
|
EXPECT_EQ(0, allocator_.Size());
|
|
|
|
// Allocate 1 to become misaligned.
|
|
Allocate(1, 0);
|
|
|
|
// 4-align.
|
|
EXPECT_EQ(3, allocator_.Align(4));
|
|
EXPECT_EQ(4, allocator_.NextSlot(1));
|
|
EXPECT_EQ(4, allocator_.NextSlot(2));
|
|
EXPECT_EQ(4, allocator_.NextSlot(4));
|
|
EXPECT_EQ(4, allocator_.Size());
|
|
|
|
// Allocate 2 to become misaligned.
|
|
Allocate(2, 4);
|
|
|
|
// 4-align.
|
|
EXPECT_EQ(2, allocator_.Align(4));
|
|
EXPECT_EQ(8, allocator_.NextSlot(1));
|
|
EXPECT_EQ(8, allocator_.NextSlot(2));
|
|
EXPECT_EQ(8, allocator_.NextSlot(4));
|
|
EXPECT_EQ(8, allocator_.Size());
|
|
|
|
// No change when we're already aligned.
|
|
EXPECT_EQ(0, allocator_.Align(2));
|
|
EXPECT_EQ(8, allocator_.NextSlot(1));
|
|
EXPECT_EQ(8, allocator_.NextSlot(2));
|
|
EXPECT_EQ(8, allocator_.NextSlot(4));
|
|
EXPECT_EQ(8, allocator_.Size());
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|