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