node/deps/v8/test/unittests/compiler/frame-unittest.cc
Michaël Zasso a7cbf19a82
deps: update V8 to 9.1.269.36
PR-URL: https://github.com/nodejs/node/pull/38273
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Mary Marchini <oss@mmarchini.me>
2021-06-10 11:10:13 +02:00

243 lines
8.8 KiB
C++

// Copyright 2021 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/compiler/frame.h"
#include "src/codegen/aligned-slot-allocator.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
namespace compiler {
namespace {
constexpr int kSlotSize = AlignedSlotAllocator::kSlotSize;
constexpr int kFixed1 = 1;
constexpr int kFixed3 = 3;
} // namespace
class FrameTest : public ::testing::Test {
public:
FrameTest() = default;
~FrameTest() override = default;
};
TEST_F(FrameTest, Constructor) {
Frame frame(kFixed3);
EXPECT_EQ(kFixed3, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, ReserveSpillSlots) {
Frame frame(kFixed3);
constexpr int kReserve2 = 2;
frame.ReserveSpillSlots(kReserve2);
EXPECT_EQ(kFixed3 + kReserve2, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(kReserve2, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, EnsureReturnSlots) {
Frame frame(kFixed3);
constexpr int kReturn3 = 3;
constexpr int kReturn5 = 5;
constexpr int kReturn2 = 2;
frame.EnsureReturnSlots(kReturn3);
EXPECT_EQ(kFixed3 + kReturn3, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn3, frame.GetReturnSlotCount());
// Returns should grow by 2 slots.
frame.EnsureReturnSlots(kReturn5);
EXPECT_EQ(kFixed3 + kReturn5, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn5, frame.GetReturnSlotCount());
// Returns shouldn't grow.
frame.EnsureReturnSlots(kReturn2);
EXPECT_EQ(kFixed3 + kReturn5, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn5, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSavedCalleeRegisterSlots) {
Frame frame(kFixed3);
constexpr int kFirstSlots = 2;
constexpr int kSecondSlots = 3;
frame.AllocateSavedCalleeRegisterSlots(kFirstSlots);
EXPECT_EQ(kFixed3 + kFirstSlots, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
frame.AllocateSavedCalleeRegisterSlots(kSecondSlots);
EXPECT_EQ(kFixed3 + kFirstSlots + kSecondSlots,
frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(0, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AlignSavedCalleeRegisterSlots) {
Frame frame(kFixed3);
constexpr int kSlots = 2; // An even number leaves the slots misaligned.
frame.AllocateSavedCalleeRegisterSlots(kSlots);
// Align, which should add 1 padding slot.
frame.AlignSavedCalleeRegisterSlots(2 * kSlotSize);
EXPECT_EQ(kFixed3 + kSlots + 1, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(1, frame.GetSpillSlotCount()); // padding
EXPECT_EQ(0, frame.GetReturnSlotCount());
// Align again, which should not add a padding slot.
frame.AlignSavedCalleeRegisterSlots(2 * kSlotSize);
EXPECT_EQ(kFixed3 + kSlots + 1, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(1, frame.GetSpillSlotCount()); // padding
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSpillSlotAligned) {
Frame frame(kFixed1);
// Allocate a quad slot, which must add 3 padding slots. Frame returns the
// last index of the 4 slot allocation.
int end = kFixed1 + 3 + 4;
int slot = kFixed1 + 3 + 4 - 1;
EXPECT_EQ(slot, frame.AllocateSpillSlot(4 * kSlotSize, 4 * kSlotSize));
EXPECT_EQ(end, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(end - kFixed1, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
// Allocate a double slot, which should leave the first padding slot and
// take the last two slots of padding.
slot = kFixed1 + 1 + 2 - 1;
EXPECT_EQ(slot, frame.AllocateSpillSlot(2 * kSlotSize, 2 * kSlotSize));
EXPECT_EQ(end, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(end - kFixed1, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
// Allocate a single slot, which should take the last padding slot.
slot = kFixed1;
EXPECT_EQ(slot, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
EXPECT_EQ(end, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(end - kFixed1, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSpillSlotAlignedWithReturns) {
Frame frame(kFixed3);
constexpr int kReturn3 = 3;
constexpr int kReturn5 = 5;
frame.EnsureReturnSlots(kReturn3);
// Allocate a double slot, which must add 1 padding slot. This should occupy
// slots 4 and 5, and AllocateSpillSlot returns the last slot index.
EXPECT_EQ(kFixed3 + 2, frame.AllocateSpillSlot(2 * kSlotSize, 2 * kSlotSize));
EXPECT_EQ(kFixed3 + kReturn3 + 3, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(3, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn3, frame.GetReturnSlotCount());
frame.EnsureReturnSlots(kReturn5);
// Allocate a single slot, which should take the padding slot.
EXPECT_EQ(kFixed3, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
EXPECT_EQ(kFixed3 + kReturn5 + 3, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(3, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn5, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSpillSlotAndEndSpillArea) {
Frame frame(kFixed3);
// Allocate a double slot, which must add 1 padding slot.
EXPECT_EQ(kFixed3 + 2, frame.AllocateSpillSlot(2 * kSlotSize, 2 * kSlotSize));
// Allocate an unaligned double slot. This should be at the end.
EXPECT_EQ(kFixed3 + 4, frame.AllocateSpillSlot(2 * kSlotSize));
EXPECT_EQ(kFixed3 + 5, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(5, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
// Allocate a single slot. This should not be the padding slot, since that
// area has been closed by the unaligned allocation.
EXPECT_EQ(kFixed3 + 5, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
EXPECT_EQ(kFixed3 + 6, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(6, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSpillSlotOverAligned) {
Frame frame(kFixed1);
// Allocate a 4-aligned double slot, which must add 3 padding slots. This
// also terminates the slot area. Returns the starting slot in this case.
EXPECT_EQ(kFixed1 + 4, frame.AllocateSpillSlot(2 * kSlotSize, 4 * kSlotSize));
EXPECT_EQ(kFixed1 + 5, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(5, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
// Allocate a single slot. This should not use any padding slot.
EXPECT_EQ(kFixed1 + 5, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
EXPECT_EQ(kFixed1 + 6, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(6, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AllocateSpillSlotUnderAligned) {
Frame frame(kFixed1);
// Allocate a 1-aligned double slot. This also terminates the slot area.
EXPECT_EQ(kFixed1 + 1, frame.AllocateSpillSlot(2 * kSlotSize, kSlotSize));
EXPECT_EQ(kFixed1 + 2, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed1, frame.GetFixedSlotCount());
EXPECT_EQ(2, frame.GetSpillSlotCount());
EXPECT_EQ(0, frame.GetReturnSlotCount());
}
TEST_F(FrameTest, AlignFrame) {
Frame frame(kFixed3);
constexpr int kReturn3 = 3;
frame.EnsureReturnSlots(kReturn3);
// Allocate two single slots, which leaves spill slots not 2-aligned.
EXPECT_EQ(kFixed3, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
EXPECT_EQ(kFixed3 + 1, frame.AllocateSpillSlot(kSlotSize, kSlotSize));
// Align to 2 slots. This should pad the spill and return slot areas.
frame.AlignFrame(2 * kSlotSize);
EXPECT_EQ(kFixed3 + 3 + kReturn3 + 1, frame.GetTotalFrameSlotCount());
EXPECT_EQ(kFixed3, frame.GetFixedSlotCount());
EXPECT_EQ(3, frame.GetSpillSlotCount());
EXPECT_EQ(kReturn3 + 1, frame.GetReturnSlotCount());
}
} // namespace compiler
} // namespace internal
} // namespace v8