LCOV - code coverage report
Current view: top level - test/unittests/heap - memory-reducer-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 166 191 86.9 %
Date: 2019-04-17 Functions: 18 38 47.4 %

          Line data    Source code
       1             : // Copyright 2014 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 <limits>
       6             : 
       7             : #include "src/flags.h"
       8             : #include "src/heap/memory-reducer.h"
       9             : #include "testing/gtest/include/gtest/gtest.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14           0 : MemoryReducer::State DoneState() {
      15           0 :   return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0, 0);
      16             : }
      17             : 
      18           0 : MemoryReducer::State DoneState(size_t committed_memory) {
      19             :   return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0,
      20           0 :                               committed_memory);
      21             : }
      22             : 
      23           0 : MemoryReducer::State WaitState(int started_gcs, double next_gc_start_ms) {
      24             :   return MemoryReducer::State(MemoryReducer::kWait, started_gcs,
      25           0 :                               next_gc_start_ms, 1.0, 0);
      26             : }
      27             : 
      28             : 
      29           0 : MemoryReducer::State RunState(int started_gcs, double next_gc_start_ms) {
      30             :   return MemoryReducer::State(MemoryReducer::kRun, started_gcs,
      31           0 :                               next_gc_start_ms, 1.0, 0);
      32             : }
      33             : 
      34           0 : MemoryReducer::Event MarkCompactEvent(double time_ms,
      35             :                                       bool next_gc_likely_to_collect_more,
      36             :                                       size_t committed_memory) {
      37             :   MemoryReducer::Event event;
      38          11 :   event.type = MemoryReducer::kMarkCompact;
      39          11 :   event.time_ms = time_ms;
      40          11 :   event.next_gc_likely_to_collect_more = next_gc_likely_to_collect_more;
      41          11 :   event.committed_memory = committed_memory;
      42           0 :   return event;
      43             : }
      44             : 
      45           0 : MemoryReducer::Event MarkCompactEventGarbageLeft(double time_ms,
      46             :                                                  size_t committed_memory) {
      47           0 :   return MarkCompactEvent(time_ms, true, committed_memory);
      48             : }
      49             : 
      50           0 : MemoryReducer::Event MarkCompactEventNoGarbageLeft(double time_ms,
      51             :                                                    size_t committed_memory) {
      52           0 :   return MarkCompactEvent(time_ms, false, committed_memory);
      53             : }
      54             : 
      55             : 
      56           0 : MemoryReducer::Event TimerEvent(double time_ms,
      57             :                                 bool should_start_incremental_gc,
      58             :                                 bool can_start_incremental_gc) {
      59             :   MemoryReducer::Event event;
      60          16 :   event.type = MemoryReducer::kTimer;
      61          16 :   event.time_ms = time_ms;
      62          16 :   event.should_start_incremental_gc = should_start_incremental_gc;
      63          16 :   event.can_start_incremental_gc = can_start_incremental_gc;
      64           0 :   return event;
      65             : }
      66             : 
      67             : 
      68           0 : MemoryReducer::Event TimerEventLowAllocationRate(double time_ms) {
      69           0 :   return TimerEvent(time_ms, true, true);
      70             : }
      71             : 
      72             : 
      73           0 : MemoryReducer::Event TimerEventHighAllocationRate(double time_ms) {
      74           0 :   return TimerEvent(time_ms, false, true);
      75             : }
      76             : 
      77             : 
      78           0 : MemoryReducer::Event TimerEventPendingGC(double time_ms) {
      79           0 :   return TimerEvent(time_ms, true, false);
      80             : }
      81             : 
      82           0 : MemoryReducer::Event PossibleGarbageEvent(double time_ms) {
      83             :   MemoryReducer::Event event;
      84           3 :   event.type = MemoryReducer::kPossibleGarbage;
      85           3 :   event.time_ms = time_ms;
      86           0 :   return event;
      87             : }
      88             : 
      89             : 
      90       15443 : TEST(MemoryReducer, FromDoneToDone) {
      91             :   MemoryReducer::State state0(DoneState()), state1(DoneState());
      92             : 
      93           1 :   state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(0));
      94           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
      95             : 
      96           1 :   state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(0));
      97           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
      98             : 
      99           1 :   state1 = MemoryReducer::Step(state0, TimerEventPendingGC(0));
     100           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     101             : 
     102             :   state1 = MemoryReducer::Step(
     103             :       state0,
     104           2 :       MarkCompactEventGarbageLeft(0, MemoryReducer::kCommittedMemoryDelta - 1));
     105           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     106             : 
     107           1 :   state0 = DoneState(1000 * MB);
     108             :   state1 = MemoryReducer::Step(
     109           1 :       state0, MarkCompactEventGarbageLeft(
     110             :                   0, static_cast<size_t>(
     111           1 :                          1000 * MB * MemoryReducer::kCommittedMemoryFactor) -
     112           2 :                          1));
     113           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     114           1 : }
     115             : 
     116             : 
     117       15443 : TEST(MemoryReducer, FromDoneToWait) {
     118           1 :   if (!FLAG_incremental_marking) return;
     119             : 
     120             :   MemoryReducer::State state0(DoneState()), state1(DoneState());
     121             : 
     122             :   state1 = MemoryReducer::Step(
     123             :       state0,
     124           2 :       MarkCompactEventGarbageLeft(2, MemoryReducer::kCommittedMemoryDelta));
     125           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     126           2 :   EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms);
     127           2 :   EXPECT_EQ(0, state1.started_gcs);
     128           2 :   EXPECT_EQ(2, state1.last_gc_time_ms);
     129             : 
     130             :   state1 = MemoryReducer::Step(
     131             :       state0,
     132           1 :       MarkCompactEventNoGarbageLeft(2, MemoryReducer::kCommittedMemoryDelta));
     133           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     134           2 :   EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms);
     135           2 :   EXPECT_EQ(0, state1.started_gcs);
     136           2 :   EXPECT_EQ(2, state1.last_gc_time_ms);
     137             : 
     138           1 :   state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(0));
     139           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     140           1 :   EXPECT_EQ(MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     141           2 :   EXPECT_EQ(0, state1.started_gcs);
     142           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     143             : 
     144           1 :   state0 = DoneState(1000 * MB);
     145             :   state1 = MemoryReducer::Step(
     146           1 :       state0, MarkCompactEventGarbageLeft(
     147             :                   2, static_cast<size_t>(
     148           2 :                          1000 * MB * MemoryReducer::kCommittedMemoryFactor)));
     149           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     150           2 :   EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms);
     151           2 :   EXPECT_EQ(0, state1.started_gcs);
     152           2 :   EXPECT_EQ(2, state1.last_gc_time_ms);
     153             : }
     154             : 
     155             : 
     156       15443 : TEST(MemoryReducer, FromWaitToWait) {
     157           1 :   if (!FLAG_incremental_marking) return;
     158             : 
     159             :   MemoryReducer::State state0(WaitState(2, 1000.0)), state1(DoneState());
     160             : 
     161           1 :   state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(2000));
     162           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     163           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     164           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     165             : 
     166             :   state1 = MemoryReducer::Step(
     167           2 :       state0, TimerEventLowAllocationRate(state0.next_gc_start_ms - 1));
     168           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     169           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     170           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     171             : 
     172           1 :   state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
     173           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     174           2 :   EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     175           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     176             : 
     177           1 :   state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
     178           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     179           2 :   EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     180           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     181             : 
     182           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0));
     183           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     184           2 :   EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     185           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     186           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     187             : 
     188           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0));
     189           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     190           2 :   EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     191           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     192           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     193             : 
     194           1 :   state0.last_gc_time_ms = 0;
     195             :   state1 = MemoryReducer::Step(
     196             :       state0,
     197           2 :       TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 1));
     198           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     199           2 :   EXPECT_EQ(MemoryReducer::kWatchdogDelayMs + 1 + MemoryReducer::kLongDelayMs,
     200           0 :             state1.next_gc_start_ms);
     201           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     202           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     203             : 
     204           1 :   state0.last_gc_time_ms = 1;
     205           1 :   state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
     206           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     207           2 :   EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms);
     208           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     209           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     210             : }
     211             : 
     212             : 
     213       15443 : TEST(MemoryReducer, FromWaitToRun) {
     214           1 :   if (!FLAG_incremental_marking) return;
     215             : 
     216             :   MemoryReducer::State state0(WaitState(0, 1000.0)), state1(DoneState());
     217             : 
     218             :   state1 = MemoryReducer::Step(
     219           1 :       state0, TimerEventLowAllocationRate(state0.next_gc_start_ms + 1));
     220           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     221           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     222           2 :   EXPECT_EQ(state0.started_gcs + 1, state1.started_gcs);
     223             : 
     224             :   state1 = MemoryReducer::Step(
     225             :       state0,
     226           2 :       TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 2));
     227           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     228           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     229           2 :   EXPECT_EQ(state0.started_gcs + 1, state1.started_gcs);
     230           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     231             : }
     232             : 
     233             : 
     234       15443 : TEST(MemoryReducer, FromWaitToDone) {
     235           1 :   if (!FLAG_incremental_marking) return;
     236             : 
     237             :   MemoryReducer::State state0(WaitState(2, 0.0)), state1(DoneState());
     238             : 
     239           1 :   state0.started_gcs = MemoryReducer::kMaxNumberOfGCs;
     240             : 
     241           1 :   state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(2000));
     242           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     243           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     244           1 :   EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
     245           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     246             : 
     247           1 :   state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
     248           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     249           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     250           1 :   EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
     251           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     252             : 
     253           1 :   state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
     254           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     255           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     256           1 :   EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
     257           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     258             : }
     259             : 
     260             : 
     261       15443 : TEST(MemoryReducer, FromRunToRun) {
     262           1 :   if (!FLAG_incremental_marking) return;
     263             : 
     264             :   MemoryReducer::State state0(RunState(1, 0.0)), state1(DoneState());
     265             : 
     266           1 :   state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(2000));
     267           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     268           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     269           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     270           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     271             : 
     272           1 :   state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000));
     273           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     274           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     275           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     276           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     277             : 
     278           1 :   state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000));
     279           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     280           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     281           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     282           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     283             : 
     284           1 :   state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(2000));
     285           2 :   EXPECT_EQ(MemoryReducer::kRun, state1.action);
     286           1 :   EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms);
     287           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     288           1 :   EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms);
     289             : }
     290             : 
     291             : 
     292       15443 : TEST(MemoryReducer, FromRunToDone) {
     293           1 :   if (!FLAG_incremental_marking) return;
     294             : 
     295             :   MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState());
     296             : 
     297           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0));
     298           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     299           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     300           1 :   EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs);
     301           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     302             : 
     303           1 :   state0.started_gcs = MemoryReducer::kMaxNumberOfGCs;
     304             : 
     305           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0));
     306           2 :   EXPECT_EQ(MemoryReducer::kDone, state1.action);
     307           2 :   EXPECT_EQ(0, state1.next_gc_start_ms);
     308           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     309             : }
     310             : 
     311             : 
     312       15443 : TEST(MemoryReducer, FromRunToWait) {
     313           1 :   if (!FLAG_incremental_marking) return;
     314             : 
     315             :   MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState());
     316             : 
     317           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0));
     318           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     319           2 :   EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms);
     320           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     321           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     322             : 
     323           1 :   state0.started_gcs = 1;
     324             : 
     325           1 :   state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0));
     326           2 :   EXPECT_EQ(MemoryReducer::kWait, state1.action);
     327           2 :   EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms);
     328           1 :   EXPECT_EQ(state0.started_gcs, state1.started_gcs);
     329           2 :   EXPECT_EQ(2000, state1.last_gc_time_ms);
     330             : }
     331             : 
     332             : }  // namespace internal
     333        9264 : }  // namespace v8

Generated by: LCOV version 1.10