LCOV - code coverage report
Current view: top level - src/heap - scavenge-job.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 38 40 95.0 %
Date: 2017-04-26 Functions: 5 6 83.3 %

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

Generated by: LCOV version 1.10