test-incremental-marking.cc 2.95 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 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>

#ifdef __linux__
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif

#include <utility>

17
#include "src/init/v8.h"
18

19
#include "src/handles/global-handles.h"
20 21
#include "src/heap/incremental-marking.h"
#include "src/heap/spaces.h"
22
#include "src/objects/objects-inl.h"
23
#include "test/cctest/cctest.h"
24
#include "test/cctest/heap/heap-utils.h"
25 26 27 28 29

using v8::IdleTask;
using v8::Task;
using v8::Isolate;

30 31
namespace v8 {
namespace internal {
32
namespace heap {
33

34
class MockPlatform : public TestPlatform {
35
 public:
36 37 38
  MockPlatform()
      : taskrunner_(new MockTaskRunner()),
        old_platform_(i::V8::GetCurrentPlatform()) {
39 40
    // Now that it's completely constructed, make this the current platform.
    i::V8::SetPlatformForTesting(this);
41
  }
42
  ~MockPlatform() override {
43
    i::V8::SetPlatformForTesting(old_platform_);
44 45
    for (auto& task : worker_tasks_) {
      old_platform_->CallOnWorkerThread(std::move(task));
46 47
    }
    worker_tasks_.clear();
48
  }
49

50 51 52
  std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
      v8::Isolate* isolate) override {
    return taskrunner_;
53 54
  }

55 56
  void CallOnWorkerThread(std::unique_ptr<Task> task) override {
    worker_tasks_.push_back(std::move(task));
57 58
  }

59
  bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
60

61
  bool PendingTask() { return taskrunner_->PendingTask(); }
62

63
  void PerformTask() { taskrunner_->PerformTask(); }
64 65

 private:
66 67 68 69 70 71 72 73
  class MockTaskRunner : public v8::TaskRunner {
   public:
    void PostTask(std::unique_ptr<v8::Task> task) override {
      task_ = std::move(task);
    }

    void PostDelayedTask(std::unique_ptr<Task> task,
                         double delay_in_seconds) override {
74
      task_ = std::move(task);
75
    }
76 77 78 79 80

    void PostIdleTask(std::unique_ptr<IdleTask> task) override {
      UNREACHABLE();
    }

81
    bool IdleTasksEnabled() override { return false; }
82 83 84 85 86 87 88 89 90 91 92 93 94

    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_;
95
  std::vector<std::unique_ptr<Task>> worker_tasks_;
96
  v8::Platform* old_platform_;
97 98
};

99
TEST(IncrementalMarkingUsingTasks) {
100
  if (!i::FLAG_incremental_marking) return;
101
  FLAG_stress_incremental_marking = false;
102
  CcTest::InitializeVM();
103
  MockPlatform platform;
104
  i::heap::SimulateFullSpace(CcTest::heap()->old_space());
105 106
  i::IncrementalMarking* marking = CcTest::heap()->incremental_marking();
  marking->Stop();
107
  marking->Start(i::GarbageCollectionReason::kTesting);
108 109 110
  CHECK(platform.PendingTask());
  while (platform.PendingTask()) {
    platform.PerformTask();
111 112 113 114
  }
  CHECK(marking->IsStopped());
}

115
}  // namespace heap
116 117
}  // namespace internal
}  // namespace v8