1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <limits>
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/gc-idle-time-handler.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass GCIdleTimeHandlerTest : public ::testing::Test {
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandlerTest() {}
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~GCIdleTimeHandlerTest() {}
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler* handler() { return &handler_; }
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState DefaultHeapState() {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeHandler::HeapState result;
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.contexts_disposed = 0;
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.size_of_objects = kSizeOfObjects;
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.incremental_marking_stopped = false;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.can_start_incremental_marking = true;
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.sweeping_in_progress = false;
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.available_new_space_memory = kNewSpaceCapacity;
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.new_space_capacity = kNewSpaceCapacity;
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.new_space_allocation_throughput_in_bytes_per_ms =
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kNewSpaceAllocationThroughput;
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kSizeOfObjects = 100 * MB;
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kMarkCompactSpeed = 200 * KB;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kMarkingSpeed = 200 * KB;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kScavengeSpeed = 100 * KB;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kNewSpaceCapacity = 1 * MB;
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kNewSpaceAllocationThroughput = 10 * KB;
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler handler_;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          GCIdleTimeHandler::kConservativeTimeRatio),
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      step_size);
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t marking_speed_in_bytes_per_millisecond = 100;
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      1, marking_speed_in_bytes_per_millisecond);
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                GCIdleTimeHandler::kConservativeTimeRatio),
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            step_size);
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      10, std::numeric_limits<size_t>::max());
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            step_size);
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      std::numeric_limits<size_t>::max(), 10);
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            step_size);
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkCompactTimeInitial) {
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = 100 * MB;
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, 0);
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeMarkCompactSpeed,
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            time);
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkCompactTimeNonZero) {
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = 100 * MB;
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = 1 * MB;
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(size / speed, time);
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = std::numeric_limits<size_t>::max();
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = 1;
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = 1 * MB;
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, 0);
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeScavengeSpeed, time);
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, EstimateScavengeTimeNonZero) {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = 1 * MB;
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = 1 * MB;
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, speed);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(size / speed, time);
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, ScavangeMayHappenSoonInitial) {
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t available = 100 * KB;
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, 0));
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroFalse) {
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t available = (GCIdleTimeHandler::kMaxFrameRenderingIdleTime + 1) * KB;
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = 1 * KB;
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroTrue) {
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t available = GCIdleTimeHandler::kMaxFrameRenderingIdleTime * KB;
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = 1 * KB;
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_TRUE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.contexts_disposed = 1;
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms =
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>((heap_state.size_of_objects + speed - 1) / speed);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_FULL_GC, action.type);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.contexts_disposed = 1;
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.contexts_disposed = 1;
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<size_t>(action.parameter));
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_LT(0, action.parameter);
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<size_t>(action.parameter));
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_LT(0, action.parameter);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_NOTHING, action.type);
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, StopEventually1) {
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(DO_FULL_GC, action.type);
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyIdleMarkCompact();
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DONE, action.type);
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, StopEventually2) {
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // In this case we emulate incremental marking steps that finish with a
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // full gc.
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyIdleMarkCompact();
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DONE, action.type);
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(DO_FULL_GC, action.type);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyIdleMarkCompact();
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DONE, action.type);
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emulate mutator work.
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyScavenge();
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  action = handler()->Compute(idle_time_ms, heap_state);
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_FULL_GC, action.type);
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (action.type == DONE) break;
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // In this case we try to emulate incremental marking steps the finish with
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // a full gc.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyIdleMarkCompact();
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DONE, action.type);
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emulate mutator work.
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyScavenge();
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = true;
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  action = handler()->Compute(idle_time_ms, heap_state);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, Scavenge) {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.available_new_space_memory =
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kNewSpaceAllocationThroughput * idle_time_ms;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_SCAVENGE, action.type);
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.can_start_incremental_marking = false;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = true;
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.available_new_space_memory =
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kNewSpaceAllocationThroughput * idle_time_ms;
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_SCAVENGE, action.type);
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.available_new_space_memory = kNewSpaceCapacity;
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  action = handler()->Compute(idle_time_ms, heap_state);
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_NOTHING, action.type);
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 0;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_NOTHING, action.type);
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) {
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idle_time_ms = 10;
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (action.type == DONE) break;
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // In this case we try to emulate incremental marking steps the finish with
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // a full gc.
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyIdleMarkCompact();
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emulate mutator work.
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handler()->NotifyScavenge();
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  action = handler()->Compute(0, heap_state);
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(DO_NOTHING, action.type);
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
349