49c507dc99
Remove cctest's ability to run multiple tests (which has long been deprecated and mostly broken). We can then make platform & V8 initialisation be part of running the test's Run method. In particular, this allows us to inject custom logic into the platform initialisation, like setting up a platform wrapper. Add a TEST_WITH_PLATFORM which exercises this by registering a platform factory on the test, and wrapping the default platform using this factory. This allows these tests to guarantee that the lifetime of the platform is longer than the lifetime of the isolate. As a result of this, we can also remove the complexity around draining platform state in the TestPlatform (since it will now have a longer lifetime than the Isolate using it), and as a drive-by clean up the TestPlaform to use a CcTest-global "default platform" instead of trying to scope over the "current" platform. As another drive-by, change the linked-list of CcTests and the linear search through it into an std::map of tests. Change-Id: I610f6312fe042f29f45cc4dfba311e4184bc7759 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3569223 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#79772}
138 lines
3.8 KiB
C++
138 lines
3.8 KiB
C++
// Copyright 2015 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 <stdlib.h>
|
|
|
|
#include "src/heap/safepoint.h"
|
|
|
|
#ifdef __linux__
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <utility>
|
|
|
|
#include "src/handles/global-handles.h"
|
|
#include "src/heap/gc-tracer.h"
|
|
#include "src/heap/incremental-marking.h"
|
|
#include "src/heap/spaces.h"
|
|
#include "src/init/v8.h"
|
|
#include "src/objects/objects-inl.h"
|
|
#include "test/cctest/cctest.h"
|
|
#include "test/cctest/heap/heap-utils.h"
|
|
|
|
using v8::IdleTask;
|
|
using v8::Task;
|
|
using v8::Isolate;
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace heap {
|
|
|
|
class MockPlatform : public TestPlatform {
|
|
public:
|
|
MockPlatform() : taskrunner_(new MockTaskRunner()) {}
|
|
~MockPlatform() override {
|
|
for (auto& task : worker_tasks_) {
|
|
CcTest::default_platform()->CallOnWorkerThread(std::move(task));
|
|
}
|
|
worker_tasks_.clear();
|
|
}
|
|
|
|
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
|
|
v8::Isolate* isolate) override {
|
|
return taskrunner_;
|
|
}
|
|
|
|
void CallOnWorkerThread(std::unique_ptr<Task> task) override {
|
|
worker_tasks_.push_back(std::move(task));
|
|
}
|
|
|
|
bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
|
|
|
|
bool PendingTask() { return taskrunner_->PendingTask(); }
|
|
|
|
void PerformTask() { taskrunner_->PerformTask(); }
|
|
|
|
private:
|
|
class MockTaskRunner : public v8::TaskRunner {
|
|
public:
|
|
void PostTask(std::unique_ptr<v8::Task> task) override {
|
|
task_ = std::move(task);
|
|
}
|
|
|
|
void PostNonNestableTask(std::unique_ptr<Task> task) override {
|
|
PostTask(std::move(task));
|
|
}
|
|
|
|
void PostDelayedTask(std::unique_ptr<Task> task,
|
|
double delay_in_seconds) override {
|
|
PostTask(std::move(task));
|
|
}
|
|
|
|
void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
|
|
double delay_in_seconds) override {
|
|
PostTask(std::move(task));
|
|
}
|
|
|
|
void PostIdleTask(std::unique_ptr<IdleTask> task) override {
|
|
UNREACHABLE();
|
|
}
|
|
|
|
bool IdleTasksEnabled() override { return false; }
|
|
bool NonNestableTasksEnabled() const override { return true; }
|
|
bool NonNestableDelayedTasksEnabled() const override { return true; }
|
|
|
|
bool PendingTask() { return task_ != nullptr; }
|
|
|
|
void PerformTask() {
|
|
std::unique_ptr<Task> task = std::move(task_);
|
|
task->Run();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<Task> task_;
|
|
};
|
|
|
|
std::shared_ptr<MockTaskRunner> taskrunner_;
|
|
std::vector<std::unique_ptr<Task>> worker_tasks_;
|
|
};
|
|
|
|
TEST_WITH_PLATFORM(IncrementalMarkingUsingTasks, MockPlatform) {
|
|
if (!i::FLAG_incremental_marking) return;
|
|
FLAG_stress_concurrent_allocation = false; // For SimulateFullSpace.
|
|
FLAG_stress_incremental_marking = false;
|
|
v8::Isolate* isolate = CcTest::isolate();
|
|
{
|
|
v8::HandleScope handle_scope(isolate);
|
|
v8::Local<v8::Context> context = CcTest::NewContext(isolate);
|
|
v8::Context::Scope context_scope(context);
|
|
Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
|
Heap* heap = i_isolate->heap();
|
|
|
|
i::heap::SimulateFullSpace(heap->old_space());
|
|
i::IncrementalMarking* marking = heap->incremental_marking();
|
|
marking->Stop();
|
|
{
|
|
SafepointScope scope(heap);
|
|
heap->tracer()->StartCycle(
|
|
GarbageCollector::MARK_COMPACTOR, GarbageCollectionReason::kTesting,
|
|
"collector cctest", GCTracer::MarkingType::kIncremental);
|
|
marking->Start(i::GarbageCollectionReason::kTesting);
|
|
}
|
|
CHECK(platform.PendingTask());
|
|
while (platform.PendingTask()) {
|
|
platform.PerformTask();
|
|
}
|
|
CHECK(marking->IsStopped());
|
|
}
|
|
}
|
|
|
|
} // namespace heap
|
|
} // namespace internal
|
|
} // namespace v8
|