v8/test/unittests/heap/allocation-observer-unittest.cc
Shu-yu Guo 76372353c1 Revert "Reland "[heap] Invoke allocation observers before limiting the LAB""
This reverts commit dbbccae19a.

Reason for revert: Deadlock in TSAN with stress:
https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux64%20TSAN/44651/overview

Original change's description:
> Reland "[heap] Invoke allocation observers before limiting the LAB"
>
> This is a reland of commit 39d387bb72
>
> Original change's description:
> > [heap] Invoke allocation observers before limiting the LAB
> >
> > Currently whenever we reach a step we get a small LAB the same size as
> > the allocated object. This is becuase the remaining step size is smaller
> > then the current allocation.
> > Invoking observers before limiting the LAB, and thus updating step
> > sizes, should eliminate the small LAB we get whenever we reach a step.
> >
> > Drive-by: remove redundant method arguments.
> >
> > Bug: v8:12612
> > Change-Id: Ied92a947308368d3b289e246fdb4f40ac5e5981f
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4013683
> > Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> > Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> > Commit-Queue: Omer Katz <omerkatz@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#84157}
>
> Bug: v8:12612, v8:13465
> Change-Id: I40fb930a755cb5decccd932c4d25ed7d5d224da4
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4020177
> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Commit-Queue: Omer Katz <omerkatz@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#84328}

Bug: v8:12612, v8:13465
Change-Id: I70df00448c7413999b91412343915c503baf0dd3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4035252
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Owners-Override: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84345}
2022-11-17 23:05:37 +00:00

181 lines
5.2 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/heap/allocation-observer.h"
#include "src/base/logging.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
namespace {
class UnusedObserver : public AllocationObserver {
public:
explicit UnusedObserver(size_t step_size) : AllocationObserver(step_size) {}
void Step(int bytes_allocated, Address soon_object, size_t size) override {
CHECK(false);
}
};
} // namespace
TEST(AllocationObserverTest, AddAndRemoveUnusedObservers) {
AllocationCounter counter;
CHECK(!counter.IsActive());
UnusedObserver observer100(100);
UnusedObserver observer200(200);
counter.AddAllocationObserver(&observer200);
CHECK_EQ(counter.NextBytes(), 200);
counter.AddAllocationObserver(&observer100);
CHECK_EQ(counter.NextBytes(), 100);
counter.AdvanceAllocationObservers(90);
CHECK_EQ(counter.NextBytes(), 10);
counter.RemoveAllocationObserver(&observer100);
CHECK_EQ(counter.NextBytes(), 110);
counter.RemoveAllocationObserver(&observer200);
CHECK(!counter.IsActive());
}
namespace {
class VerifyStepObserver : public AllocationObserver {
public:
explicit VerifyStepObserver(size_t step_size)
: AllocationObserver(step_size) {}
void Step(int bytes_allocated, Address soon_object, size_t size) override {
CHECK(!do_not_invoke_);
invocations_++;
CHECK_EQ(expected_bytes_allocated_, bytes_allocated);
CHECK_EQ(expected_size_, size);
}
void ExpectNoInvocation() { do_not_invoke_ = true; }
void Expect(int expected_bytes_allocated, size_t expected_size) {
do_not_invoke_ = false;
expected_bytes_allocated_ = expected_bytes_allocated;
expected_size_ = expected_size;
}
int Invocations() { return invocations_; }
private:
bool do_not_invoke_ = false;
int invocations_ = 0;
int expected_bytes_allocated_ = 0;
size_t expected_size_ = 0;
};
} // namespace
TEST(AllocationObserverTest, Step) {
AllocationCounter counter;
CHECK(!counter.IsActive());
const Address kSomeObjectAddress = 8;
VerifyStepObserver observer100(100);
VerifyStepObserver observer200(200);
counter.AddAllocationObserver(&observer100);
counter.AddAllocationObserver(&observer200);
observer100.Expect(90, 8);
observer200.ExpectNoInvocation();
counter.AdvanceAllocationObservers(90);
counter.InvokeAllocationObservers(kSomeObjectAddress, 8, 10);
CHECK_EQ(observer100.Invocations(), 1);
CHECK_EQ(observer200.Invocations(), 0);
CHECK_EQ(counter.NextBytes(),
10 /* aligned_object_size */ + 100 /* smallest step size*/);
observer100.Expect(90, 16);
observer200.Expect(180, 16);
counter.AdvanceAllocationObservers(90);
counter.InvokeAllocationObservers(kSomeObjectAddress, 16, 20);
CHECK_EQ(observer100.Invocations(), 2);
CHECK_EQ(observer200.Invocations(), 1);
CHECK_EQ(counter.NextBytes(),
20 /* aligned_object_size */ + 100 /* smallest step size*/);
}
namespace {
class RecursiveAddObserver : public AllocationObserver {
public:
explicit RecursiveAddObserver(size_t step_size, AllocationCounter* counter,
AllocationObserver* observer)
: AllocationObserver(step_size), counter_(counter), observer_(observer) {}
void Step(int bytes_allocated, Address soon_object, size_t size) override {
counter_->AddAllocationObserver(observer_);
}
private:
AllocationCounter* counter_;
AllocationObserver* observer_;
};
} // namespace
TEST(AllocationObserverTest, RecursiveAdd) {
AllocationCounter counter;
const Address kSomeObjectAddress = 8;
UnusedObserver observer50(50);
RecursiveAddObserver observer100(100, &counter, &observer50);
counter.AddAllocationObserver(&observer100);
CHECK_EQ(counter.NextBytes(), 100);
counter.AdvanceAllocationObservers(90);
counter.InvokeAllocationObservers(kSomeObjectAddress, 10, 10);
CHECK_EQ(counter.NextBytes(),
10 /* aligned_object_size */ + 50 /* smallest step size */);
}
namespace {
class RecursiveRemoveObserver : public AllocationObserver {
public:
explicit RecursiveRemoveObserver(size_t step_size, AllocationCounter* counter,
AllocationObserver* observer)
: AllocationObserver(step_size), counter_(counter), observer_(observer) {}
void Step(int bytes_allocated, Address soon_object, size_t size) override {
counter_->RemoveAllocationObserver(observer_);
}
private:
AllocationCounter* counter_;
AllocationObserver* observer_;
};
} // namespace
TEST(AllocationObserverTest, RecursiveRemove) {
AllocationCounter counter;
const Address kSomeObjectAddress = 8;
UnusedObserver observer75(75);
RecursiveRemoveObserver observer50(50, &counter, &observer75);
counter.AddAllocationObserver(&observer50);
counter.AddAllocationObserver(&observer75);
CHECK_EQ(counter.NextBytes(), 50);
counter.AdvanceAllocationObservers(40);
counter.InvokeAllocationObservers(kSomeObjectAddress, 10, 10);
CHECK_EQ(counter.NextBytes(),
10 /* aligned_object_size */ + 50 /* smallest step size */);
}
} // namespace internal
} // namespace v8