2014-08-20 10:33:03 +00:00
|
|
|
// Copyright 2014 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.
|
|
|
|
|
|
|
|
#ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
|
|
|
|
#define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
|
|
|
|
|
|
|
|
#include "src/globals.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
enum GCIdleTimeActionType {
|
2014-09-16 09:21:09 +00:00
|
|
|
DONE,
|
2014-08-21 14:42:22 +00:00
|
|
|
DO_NOTHING,
|
|
|
|
DO_INCREMENTAL_MARKING,
|
|
|
|
DO_SCAVENGE,
|
2014-08-22 12:32:12 +00:00
|
|
|
DO_FULL_GC,
|
|
|
|
DO_FINALIZE_SWEEPING
|
2014-08-21 14:42:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class GCIdleTimeAction {
|
|
|
|
public:
|
2014-09-16 09:21:09 +00:00
|
|
|
static GCIdleTimeAction Done() {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DONE;
|
|
|
|
result.parameter = 0;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-09-16 09:21:09 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
static GCIdleTimeAction Nothing() {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DO_NOTHING;
|
|
|
|
result.parameter = 0;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-08-21 14:42:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
2014-08-22 12:32:12 +00:00
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
static GCIdleTimeAction IncrementalMarking(intptr_t step_size) {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DO_INCREMENTAL_MARKING;
|
|
|
|
result.parameter = step_size;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-08-21 14:42:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
2014-08-22 12:32:12 +00:00
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
static GCIdleTimeAction Scavenge() {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DO_SCAVENGE;
|
|
|
|
result.parameter = 0;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-08-21 14:42:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
2014-08-22 12:32:12 +00:00
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
static GCIdleTimeAction FullGC() {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DO_FULL_GC;
|
|
|
|
result.parameter = 0;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-08-21 14:42:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-08-22 12:32:12 +00:00
|
|
|
static GCIdleTimeAction FinalizeSweeping() {
|
|
|
|
GCIdleTimeAction result;
|
|
|
|
result.type = DO_FINALIZE_SWEEPING;
|
|
|
|
result.parameter = 0;
|
2014-12-03 10:03:14 +00:00
|
|
|
result.additional_work = false;
|
2014-08-22 12:32:12 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-09-01 12:06:16 +00:00
|
|
|
void Print();
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
GCIdleTimeActionType type;
|
|
|
|
intptr_t parameter;
|
2014-12-03 10:03:14 +00:00
|
|
|
bool additional_work;
|
2014-08-21 14:42:22 +00:00
|
|
|
};
|
|
|
|
|
2014-08-22 09:18:10 +00:00
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
class GCTracer;
|
|
|
|
|
2014-08-20 10:33:03 +00:00
|
|
|
// The idle time handler makes decisions about which garbage collection
|
|
|
|
// operations are executing during IdleNotification.
|
|
|
|
class GCIdleTimeHandler {
|
|
|
|
public:
|
|
|
|
// If we haven't recorded any incremental marking events yet, we carefully
|
|
|
|
// mark with a conservative lower bound for the marking speed.
|
2014-08-20 15:37:43 +00:00
|
|
|
static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
|
|
|
|
|
|
|
|
// Maximum marking step size returned by EstimateMarkingStepSize.
|
|
|
|
static const size_t kMaximumMarkingStepSize = 700 * MB;
|
2014-08-20 10:33:03 +00:00
|
|
|
|
|
|
|
// We have to make sure that we finish the IdleNotification before
|
|
|
|
// idle_time_in_ms. Hence, we conservatively prune our workload estimate.
|
|
|
|
static const double kConservativeTimeRatio;
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
// If we haven't recorded any mark-compact events yet, we use
|
|
|
|
// conservative lower bound for the mark-compact speed.
|
|
|
|
static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
|
|
|
|
|
2014-11-27 12:39:41 +00:00
|
|
|
// If we haven't recorded any final incremental mark-compact events yet, we
|
|
|
|
// use conservative lower bound for the mark-compact speed.
|
|
|
|
static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
|
|
|
|
2 * MB;
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
// Maximum mark-compact time returned by EstimateMarkCompactTime.
|
2014-08-22 11:36:23 +00:00
|
|
|
static const size_t kMaxMarkCompactTimeInMs;
|
2014-08-21 14:42:22 +00:00
|
|
|
|
2014-11-27 12:39:41 +00:00
|
|
|
// Maximum final incremental mark-compact time returned by
|
|
|
|
// EstimateFinalIncrementalMarkCompactTime.
|
|
|
|
static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
|
|
|
|
|
2014-08-22 13:26:29 +00:00
|
|
|
// Number of idle mark-compact events, after which idle handler will finish
|
|
|
|
// idle round.
|
|
|
|
static const int kMaxMarkCompactsInIdleRound;
|
|
|
|
|
|
|
|
// Number of scavenges that will trigger start of new idle round.
|
|
|
|
static const int kIdleScavengeThreshold;
|
|
|
|
|
2015-03-19 19:41:02 +00:00
|
|
|
// This is the maximum scheduled idle time. Note that it can be more than
|
|
|
|
// 16 ms when there is currently no rendering going on.
|
|
|
|
static const size_t kMaxScheduledIdleTime = 50;
|
2014-09-16 12:48:59 +00:00
|
|
|
|
2015-03-30 11:39:50 +00:00
|
|
|
// We conservatively assume that in the next kTimeUntilNextIdleEvent ms
|
|
|
|
// no idle notification happens.
|
|
|
|
static const size_t kTimeUntilNextIdleEvent = 100;
|
|
|
|
|
2014-09-16 13:00:05 +00:00
|
|
|
// If we haven't recorded any scavenger events yet, we use a conservative
|
|
|
|
// lower bound for the scavenger speed.
|
|
|
|
static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
|
|
|
|
|
2014-11-07 09:36:49 +00:00
|
|
|
// If contexts are disposed at a higher rate a full gc is triggered.
|
|
|
|
static const double kHighContextDisposalRate;
|
|
|
|
|
2014-12-02 11:24:58 +00:00
|
|
|
// Incremental marking step time.
|
|
|
|
static const size_t kIncrementalMarkingStepTimeInMs = 1;
|
|
|
|
|
2015-03-16 14:51:09 +00:00
|
|
|
static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
|
|
|
|
|
2014-11-17 09:16:14 +00:00
|
|
|
class HeapState {
|
|
|
|
public:
|
|
|
|
void Print();
|
|
|
|
|
2014-08-22 09:18:10 +00:00
|
|
|
int contexts_disposed;
|
2014-11-07 09:36:49 +00:00
|
|
|
double contexts_disposal_rate;
|
2014-08-22 09:18:10 +00:00
|
|
|
size_t size_of_objects;
|
|
|
|
bool incremental_marking_stopped;
|
|
|
|
bool can_start_incremental_marking;
|
2014-08-22 12:32:12 +00:00
|
|
|
bool sweeping_in_progress;
|
2015-03-30 10:05:25 +00:00
|
|
|
bool sweeping_completed;
|
2014-08-22 13:02:11 +00:00
|
|
|
size_t mark_compact_speed_in_bytes_per_ms;
|
|
|
|
size_t incremental_marking_speed_in_bytes_per_ms;
|
2014-11-27 12:39:41 +00:00
|
|
|
size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
|
2014-09-16 13:00:05 +00:00
|
|
|
size_t scavenge_speed_in_bytes_per_ms;
|
2014-10-02 07:21:53 +00:00
|
|
|
size_t used_new_space_size;
|
2014-09-16 13:00:05 +00:00
|
|
|
size_t new_space_capacity;
|
2014-09-18 08:44:46 +00:00
|
|
|
size_t new_space_allocation_throughput_in_bytes_per_ms;
|
2014-08-22 09:18:10 +00:00
|
|
|
};
|
|
|
|
|
2014-08-21 14:42:22 +00:00
|
|
|
GCIdleTimeHandler()
|
|
|
|
: mark_compacts_since_idle_round_started_(0),
|
|
|
|
scavenges_since_last_idle_round_(0) {}
|
|
|
|
|
2014-11-28 10:59:18 +00:00
|
|
|
GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
|
2014-08-21 14:42:22 +00:00
|
|
|
|
|
|
|
void NotifyIdleMarkCompact() {
|
|
|
|
if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
|
|
|
|
++mark_compacts_since_idle_round_started_;
|
|
|
|
if (mark_compacts_since_idle_round_started_ ==
|
|
|
|
kMaxMarkCompactsInIdleRound) {
|
|
|
|
scavenges_since_last_idle_round_ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NotifyScavenge() { ++scavenges_since_last_idle_round_; }
|
|
|
|
|
|
|
|
static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
|
|
|
|
size_t marking_speed_in_bytes_per_ms);
|
|
|
|
|
|
|
|
static size_t EstimateMarkCompactTime(
|
|
|
|
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
|
|
|
|
|
2014-11-27 12:39:41 +00:00
|
|
|
static size_t EstimateFinalIncrementalMarkCompactTime(
|
|
|
|
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
|
|
|
|
|
2014-10-13 16:27:55 +00:00
|
|
|
static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
|
|
|
|
size_t size_of_objects,
|
|
|
|
size_t mark_compact_speed_in_bytes_per_ms);
|
|
|
|
|
2014-12-03 13:13:49 +00:00
|
|
|
static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
|
2014-11-24 19:19:04 +00:00
|
|
|
double contexts_disposal_rate);
|
|
|
|
|
2014-11-27 12:39:41 +00:00
|
|
|
static bool ShouldDoFinalIncrementalMarkCompact(
|
|
|
|
size_t idle_time_in_ms, size_t size_of_objects,
|
|
|
|
size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
|
|
|
|
|
2015-03-16 14:51:09 +00:00
|
|
|
static bool ShouldDoOverApproximateWeakClosure(size_t idle_time_in_ms);
|
|
|
|
|
2014-10-13 16:27:55 +00:00
|
|
|
static bool ShouldDoScavenge(
|
2014-10-02 07:21:53 +00:00
|
|
|
size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
|
|
|
|
size_t scavenger_speed_in_bytes_per_ms,
|
2014-09-18 08:44:46 +00:00
|
|
|
size_t new_space_allocation_throughput_in_bytes_per_ms);
|
|
|
|
|
2014-08-20 10:33:03 +00:00
|
|
|
private:
|
2014-08-21 14:42:22 +00:00
|
|
|
void StartIdleRound() { mark_compacts_since_idle_round_started_ = 0; }
|
2014-09-16 13:00:05 +00:00
|
|
|
bool IsMarkCompactIdleRoundFinished() {
|
2014-08-21 14:42:22 +00:00
|
|
|
return mark_compacts_since_idle_round_started_ ==
|
|
|
|
kMaxMarkCompactsInIdleRound;
|
|
|
|
}
|
|
|
|
bool EnoughGarbageSinceLastIdleRound() {
|
|
|
|
return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mark_compacts_since_idle_round_started_;
|
|
|
|
int scavenges_since_last_idle_round_;
|
|
|
|
|
2014-08-20 10:33:03 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
|
|
|
|
|
|
|
#endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
|