// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/heap/scavenge-job.h"

#include "src/base/platform/time.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/isolate.h"
#include "src/v8.h"

namespace v8 {
namespace internal {


const double ScavengeJob::kMaxAllocationLimitAsFractionOfNewSpace = 0.8;

void ScavengeJob::IdleTask::RunInternal(double deadline_in_seconds) {
  Heap* heap = isolate()->heap();
  double deadline_in_ms =
      deadline_in_seconds *
      static_cast<double>(base::Time::kMillisecondsPerSecond);
  double start_ms = heap->MonotonicallyIncreasingTimeInMs();
  double idle_time_in_ms = deadline_in_ms - start_ms;
  size_t scavenge_speed_in_bytes_per_ms =
      static_cast<size_t>(heap->tracer()->ScavengeSpeedInBytesPerMillisecond());
  size_t new_space_size = heap->new_space()->Size();
  size_t new_space_capacity = heap->new_space()->Capacity();

  job_->NotifyIdleTask();

  if (ReachedIdleAllocationLimit(scavenge_speed_in_bytes_per_ms, new_space_size,
                                 new_space_capacity)) {
    if (EnoughIdleTimeForScavenge(
            idle_time_in_ms, scavenge_speed_in_bytes_per_ms, new_space_size)) {
      heap->CollectGarbage(NEW_SPACE, "idle task: scavenge");
    } else {
      // Immediately request another idle task that can get larger idle time.
      job_->RescheduleIdleTask(heap);
    }
  }
}


bool ScavengeJob::ReachedIdleAllocationLimit(
    size_t scavenge_speed_in_bytes_per_ms, size_t new_space_size,
    size_t new_space_capacity) {
  if (scavenge_speed_in_bytes_per_ms == 0) {
    scavenge_speed_in_bytes_per_ms = kInitialScavengeSpeedInBytesPerMs;
  }

  // Set the allocation limit to the number of bytes we can scavenge in an
  // average idle task.
  size_t allocation_limit = kAverageIdleTimeMs * scavenge_speed_in_bytes_per_ms;

  // Keep the limit smaller than the new space capacity.
  allocation_limit =
      Min(allocation_limit,
          static_cast<size_t>(new_space_capacity *
                              kMaxAllocationLimitAsFractionOfNewSpace));
  // Adjust the limit to take into account bytes that will be allocated until
  // the next check.
  allocation_limit = allocation_limit < kBytesAllocatedBeforeNextIdleTask
                         ? 0
                         : allocation_limit - kBytesAllocatedBeforeNextIdleTask;
  // Keep the limit large enough to avoid scavenges in tiny new space.
  allocation_limit = Max(allocation_limit, kMinAllocationLimit);

  return allocation_limit <= new_space_size;
}


bool ScavengeJob::EnoughIdleTimeForScavenge(
    double idle_time_in_ms, size_t scavenge_speed_in_bytes_per_ms,
    size_t new_space_size) {
  if (scavenge_speed_in_bytes_per_ms == 0) {
    scavenge_speed_in_bytes_per_ms = kInitialScavengeSpeedInBytesPerMs;
  }
  return new_space_size <= idle_time_in_ms * scavenge_speed_in_bytes_per_ms;
}


void ScavengeJob::RescheduleIdleTask(Heap* heap) {
  // Make sure that we don't reschedule more than one time.
  // Otherwise, we might spam the scheduler with idle tasks.
  if (!idle_task_rescheduled_) {
    ScheduleIdleTask(heap);
    idle_task_rescheduled_ = true;
  }
}


void ScavengeJob::ScheduleIdleTaskIfNeeded(Heap* heap, int bytes_allocated) {
  bytes_allocated_since_the_last_task_ += bytes_allocated;
  if (bytes_allocated_since_the_last_task_ >=
      static_cast<int>(kBytesAllocatedBeforeNextIdleTask)) {
    ScheduleIdleTask(heap);
    bytes_allocated_since_the_last_task_ = 0;
    idle_task_rescheduled_ = false;
  }
}


void ScavengeJob::ScheduleIdleTask(Heap* heap) {
  if (!idle_task_pending_) {
    v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
    if (V8::GetCurrentPlatform()->IdleTasksEnabled(isolate)) {
      idle_task_pending_ = true;
      auto task = new IdleTask(heap->isolate(), this);
      V8::GetCurrentPlatform()->CallIdleOnForegroundThread(isolate, task);
    }
  }
}
}  // namespace internal
}  // namespace v8
