Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include <stdlib.h>
6 :
7 : #ifdef __linux__
8 : #include <errno.h>
9 : #include <fcntl.h>
10 : #include <sys/stat.h>
11 : #include <sys/types.h>
12 : #include <unistd.h>
13 : #endif
14 :
15 : #include <utility>
16 :
17 : #include "src/v8.h"
18 :
19 : #include "src/global-handles.h"
20 : #include "src/heap/incremental-marking.h"
21 : #include "src/heap/spaces.h"
22 : #include "src/objects-inl.h"
23 : #include "test/cctest/cctest.h"
24 : #include "test/cctest/heap/heap-utils.h"
25 :
26 : using v8::IdleTask;
27 : using v8::Task;
28 : using v8::Isolate;
29 :
30 : namespace v8 {
31 : namespace internal {
32 : namespace heap {
33 :
34 : class MockPlatform : public TestPlatform {
35 : public:
36 5 : MockPlatform()
37 : : taskrunner_(new MockTaskRunner()),
38 10 : old_platform_(i::V8::GetCurrentPlatform()) {
39 : // Now that it's completely constructed, make this the current platform.
40 5 : i::V8::SetPlatformForTesting(this);
41 5 : }
42 15 : ~MockPlatform() override {
43 5 : i::V8::SetPlatformForTesting(old_platform_);
44 75 : for (auto& task : worker_tasks_) {
45 210 : old_platform_->CallOnWorkerThread(std::move(task));
46 : }
47 5 : worker_tasks_.clear();
48 5 : }
49 :
50 40 : std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
51 : v8::Isolate* isolate) override {
52 40 : return taskrunner_;
53 : }
54 :
55 70 : void CallOnWorkerThread(std::unique_ptr<Task> task) override {
56 70 : worker_tasks_.push_back(std::move(task));
57 70 : }
58 :
59 0 : bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
60 :
61 : bool PendingTask() { return taskrunner_->PendingTask(); }
62 :
63 40 : void PerformTask() { taskrunner_->PerformTask(); }
64 :
65 : private:
66 15 : class MockTaskRunner : public v8::TaskRunner {
67 : public:
68 15 : void PostTask(std::unique_ptr<v8::Task> task) override {
69 : task_ = std::move(task);
70 15 : }
71 :
72 25 : void PostDelayedTask(std::unique_ptr<Task> task,
73 : double delay_in_seconds) override {
74 : task_ = std::move(task);
75 25 : }
76 :
77 0 : void PostIdleTask(std::unique_ptr<IdleTask> task) override {
78 0 : UNREACHABLE();
79 : }
80 :
81 0 : bool IdleTasksEnabled() override { return false; }
82 :
83 : bool PendingTask() { return task_ != nullptr; }
84 :
85 40 : void PerformTask() {
86 : std::unique_ptr<Task> task = std::move(task_);
87 40 : task->Run();
88 40 : }
89 :
90 : private:
91 : std::unique_ptr<Task> task_;
92 : };
93 :
94 : std::shared_ptr<MockTaskRunner> taskrunner_;
95 : std::vector<std::unique_ptr<Task>> worker_tasks_;
96 : v8::Platform* old_platform_;
97 : };
98 :
99 26661 : TEST(IncrementalMarkingUsingTasks) {
100 5 : if (!i::FLAG_incremental_marking) return;
101 5 : FLAG_stress_incremental_marking = false;
102 5 : CcTest::InitializeVM();
103 10 : MockPlatform platform;
104 5 : i::heap::SimulateFullSpace(CcTest::heap()->old_space());
105 5 : i::IncrementalMarking* marking = CcTest::heap()->incremental_marking();
106 5 : marking->Stop();
107 5 : marking->Start(i::GarbageCollectionReason::kTesting);
108 5 : CHECK(platform.PendingTask());
109 45 : while (platform.PendingTask()) {
110 : platform.PerformTask();
111 : }
112 5 : CHECK(marking->IsStopped());
113 : }
114 :
115 : } // namespace heap
116 : } // namespace internal
117 79968 : } // namespace v8
|