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#ifndef V8_HEAP_SCAVENGE_JOB_H_
6#define V8_HEAP_SCAVENGE_JOB_H_
7
8#include "src/cancelable-task.h"
9#include "src/globals.h"
10#include "src/heap/gc-tracer.h"
11
12namespace v8 {
13namespace internal {
14
15class Heap;
16class Isolate;
17
18
19// This class posts idle tasks and performs scavenges in the idle tasks.
20class V8_EXPORT_PRIVATE ScavengeJob {
21 public:
22  class IdleTask : public CancelableIdleTask {
23   public:
24    explicit IdleTask(Isolate* isolate, ScavengeJob* job)
25        : CancelableIdleTask(isolate), job_(job) {}
26    // CancelableIdleTask overrides.
27    void RunInternal(double deadline_in_seconds) override;
28
29   private:
30    ScavengeJob* job_;
31  };
32
33  ScavengeJob()
34      : idle_task_pending_(false),
35        idle_task_rescheduled_(false),
36        bytes_allocated_since_the_last_task_(0) {}
37
38  // Posts an idle task if the cumulative bytes allocated since the last
39  // idle task exceed kBytesAllocatedBeforeNextIdleTask.
40  void ScheduleIdleTaskIfNeeded(Heap* heap, int bytes_allocated);
41
42  // Posts an idle task ignoring the bytes allocated, but makes sure
43  // that the new idle task cannot reschedule again.
44  // This prevents infinite rescheduling.
45  void RescheduleIdleTask(Heap* heap);
46
47  bool IdleTaskPending() { return idle_task_pending_; }
48  void NotifyIdleTask() { idle_task_pending_ = false; }
49  bool IdleTaskRescheduled() { return idle_task_rescheduled_; }
50
51  static bool ReachedIdleAllocationLimit(double scavenge_speed_in_bytes_per_ms,
52                                         size_t new_space_size,
53                                         size_t new_space_capacity);
54
55  static bool EnoughIdleTimeForScavenge(double idle_time_ms,
56                                        double scavenge_speed_in_bytes_per_ms,
57                                        size_t new_space_size);
58
59  // If we haven't recorded any scavenger events yet, we use a conservative
60  // lower bound for the scavenger speed.
61  static const int kInitialScavengeSpeedInBytesPerMs = 256 * KB;
62  // Estimate of the average idle time that an idle task gets.
63  static const int kAverageIdleTimeMs = 5;
64  // The number of bytes to be allocated in new space before the next idle
65  // task is posted.
66  static const size_t kBytesAllocatedBeforeNextIdleTask = 512 * KB;
67  // The minimum size of allocated new space objects to trigger a scavenge.
68  static const size_t kMinAllocationLimit = 512 * KB;
69  // The allocation limit cannot exceed this fraction of the new space capacity.
70  static const double kMaxAllocationLimitAsFractionOfNewSpace;
71
72 private:
73  void ScheduleIdleTask(Heap* heap);
74  bool idle_task_pending_;
75  bool idle_task_rescheduled_;
76  int bytes_allocated_since_the_last_task_;
77};
78}  // namespace internal
79}  // namespace v8
80
81#endif  // V8_HEAP_SCAVENGE_JOB_H_
82