LCOV - code coverage report
Current view: top level - src/heap - scavenge-job.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 42 44 95.5 %
Date: 2019-02-19 Functions: 7 8 87.5 %

          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 "src/heap/scavenge-job.h"
       6             : 
       7             : #include "src/base/platform/time.h"
       8             : #include "src/heap/gc-tracer.h"
       9             : #include "src/heap/heap-inl.h"
      10             : #include "src/heap/heap.h"
      11             : #include "src/heap/spaces.h"
      12             : #include "src/isolate.h"
      13             : #include "src/v8.h"
      14             : #include "src/vm-state-inl.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : 
      20             : const double ScavengeJob::kMaxAllocationLimitAsFractionOfNewSpace = 0.8;
      21             : 
      22        7890 : void ScavengeJob::IdleTask::RunInternal(double deadline_in_seconds) {
      23             :   VMState<GC> state(isolate());
      24       11835 :   TRACE_EVENT_CALL_STATS_SCOPED(isolate(), "v8", "V8.Task");
      25       11835 :   Heap* heap = isolate()->heap();
      26             :   double deadline_in_ms =
      27             :       deadline_in_seconds *
      28        3945 :       static_cast<double>(base::Time::kMillisecondsPerSecond);
      29        3945 :   double start_ms = heap->MonotonicallyIncreasingTimeInMs();
      30        3945 :   double idle_time_in_ms = deadline_in_ms - start_ms;
      31             :   double scavenge_speed_in_bytes_per_ms =
      32        3945 :       heap->tracer()->ScavengeSpeedInBytesPerMillisecond();
      33        3945 :   size_t new_space_size = heap->new_space()->Size();
      34             :   size_t new_space_capacity = heap->new_space()->Capacity();
      35             : 
      36        3945 :   job_->NotifyIdleTask();
      37             : 
      38        3945 :   if (ReachedIdleAllocationLimit(scavenge_speed_in_bytes_per_ms, new_space_size,
      39             :                                  new_space_capacity)) {
      40        2130 :     if (EnoughIdleTimeForScavenge(
      41             :             idle_time_in_ms, scavenge_speed_in_bytes_per_ms, new_space_size)) {
      42        1988 :       heap->CollectGarbage(NEW_SPACE, GarbageCollectionReason::kIdleTask);
      43             :     } else {
      44             :       // Immediately request another idle task that can get larger idle time.
      45         142 :       job_->RescheduleIdleTask(heap);
      46             :     }
      47             :   }
      48        3945 : }
      49             : 
      50          11 : bool ScavengeJob::ReachedIdleAllocationLimit(
      51             :     double scavenge_speed_in_bytes_per_ms, size_t new_space_size,
      52             :     size_t new_space_capacity) {
      53        3956 :   if (scavenge_speed_in_bytes_per_ms == 0) {
      54             :     scavenge_speed_in_bytes_per_ms = kInitialScavengeSpeedInBytesPerMs;
      55             :   }
      56             : 
      57             :   // Set the allocation limit to the number of bytes we can scavenge in an
      58             :   // average idle task.
      59        3956 :   double allocation_limit = kAverageIdleTimeMs * scavenge_speed_in_bytes_per_ms;
      60             : 
      61             :   // Keep the limit smaller than the new space capacity.
      62             :   allocation_limit =
      63             :       Min<double>(allocation_limit,
      64        3956 :                   new_space_capacity * kMaxAllocationLimitAsFractionOfNewSpace);
      65             :   // Adjust the limit to take into account bytes that will be allocated until
      66             :   // the next check and keep the limit large enough to avoid scavenges in tiny
      67             :   // new space.
      68             :   allocation_limit =
      69             :       Max<double>(allocation_limit - kBytesAllocatedBeforeNextIdleTask,
      70        3956 :                   kMinAllocationLimit);
      71             : 
      72        3956 :   return allocation_limit <= new_space_size;
      73             : }
      74             : 
      75           6 : bool ScavengeJob::EnoughIdleTimeForScavenge(
      76             :     double idle_time_in_ms, double scavenge_speed_in_bytes_per_ms,
      77             :     size_t new_space_size) {
      78        2136 :   if (scavenge_speed_in_bytes_per_ms == 0) {
      79             :     scavenge_speed_in_bytes_per_ms = kInitialScavengeSpeedInBytesPerMs;
      80             :   }
      81        2136 :   return new_space_size <= idle_time_in_ms * scavenge_speed_in_bytes_per_ms;
      82             : }
      83             : 
      84             : 
      85           0 : void ScavengeJob::RescheduleIdleTask(Heap* heap) {
      86             :   // Make sure that we don't reschedule more than one time.
      87             :   // Otherwise, we might spam the scheduler with idle tasks.
      88         142 :   if (!idle_task_rescheduled_) {
      89          71 :     ScheduleIdleTask(heap);
      90          71 :     idle_task_rescheduled_ = true;
      91             :   }
      92           0 : }
      93             : 
      94             : 
      95       32825 : void ScavengeJob::ScheduleIdleTaskIfNeeded(Heap* heap, int bytes_allocated) {
      96       32825 :   bytes_allocated_since_the_last_task_ += bytes_allocated;
      97       32825 :   if (bytes_allocated_since_the_last_task_ >=
      98             :       static_cast<int>(kBytesAllocatedBeforeNextIdleTask)) {
      99       32825 :     ScheduleIdleTask(heap);
     100       32825 :     bytes_allocated_since_the_last_task_ = 0;
     101       32825 :     idle_task_rescheduled_ = false;
     102             :   }
     103       32825 : }
     104             : 
     105             : 
     106       38475 : void ScavengeJob::ScheduleIdleTask(Heap* heap) {
     107       38475 :   if (!idle_task_pending_ && !heap->IsTearingDown()) {
     108             :     v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
     109        5579 :     if (V8::GetCurrentPlatform()->IdleTasksEnabled(isolate)) {
     110        3947 :       idle_task_pending_ = true;
     111        3947 :       auto task = base::make_unique<IdleTask>(heap->isolate(), this);
     112        7894 :       V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate)->PostIdleTask(
     113       11841 :           std::move(task));
     114             :     }
     115             :   }
     116       32896 : }
     117             : }  // namespace internal
     118      178779 : }  // namespace v8

Generated by: LCOV version 1.10