}
-void GCIdleTimeHandler::HeapState::Print() {
+void GCIdleTimeHeapState::Print() {
PrintF("contexts_disposed=%d ", contexts_disposed);
PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate);
PrintF("size_of_objects=%" V8_PTR_PREFIX "d ", size_of_objects);
// (5) If incremental marking is in progress, we perform a marking step. Note,
// that this currently may trigger a full garbage collection.
GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
- HeapState heap_state) {
+ GCIdleTimeHeapState heap_state) {
if (static_cast<int>(idle_time_in_ms) <= 0) {
if (heap_state.incremental_marking_stopped) {
if (ShouldDoContextDisposalMarkCompact(
};
-class GCTracer;
+class GCIdleTimeHeapState {
+ public:
+ void Print();
+
+ int contexts_disposed;
+ double contexts_disposal_rate;
+ size_t size_of_objects;
+ bool incremental_marking_stopped;
+ bool sweeping_in_progress;
+ bool sweeping_completed;
+ bool has_low_allocation_rate;
+ size_t mark_compact_speed_in_bytes_per_ms;
+ size_t incremental_marking_speed_in_bytes_per_ms;
+ size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
+ size_t scavenge_speed_in_bytes_per_ms;
+ size_t used_new_space_size;
+ size_t new_space_capacity;
+ size_t new_space_allocation_throughput_in_bytes_per_ms;
+};
+
// The idle time handler makes decisions about which garbage collection
// operations are executing during IdleNotification.
// ensure we don't keep scheduling idle tasks and making no progress.
static const int kMaxNoProgressIdleTimes = 10;
- class HeapState {
- public:
- void Print();
-
- int contexts_disposed;
- double contexts_disposal_rate;
- size_t size_of_objects;
- bool incremental_marking_stopped;
- bool sweeping_in_progress;
- bool sweeping_completed;
- bool has_low_allocation_rate;
- size_t mark_compact_speed_in_bytes_per_ms;
- size_t incremental_marking_speed_in_bytes_per_ms;
- size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
- size_t scavenge_speed_in_bytes_per_ms;
- size_t used_new_space_size;
- size_t new_space_capacity;
- size_t new_space_allocation_throughput_in_bytes_per_ms;
- };
-
GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
- GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
+ GCIdleTimeAction Compute(double idle_time_in_ms,
+ GCIdleTimeHeapState heap_state);
void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
mark_compact_collector_(this),
store_buffer_(this),
incremental_marking_(this),
+ gc_idle_time_handler_(nullptr),
memory_reducer_(nullptr),
object_stats_(nullptr),
full_codegen_bytes_generated_(0),
void Heap::StartIdleIncrementalMarking() {
- gc_idle_time_handler_.ResetNoProgressCounter();
+ gc_idle_time_handler_->ResetNoProgressCounter();
StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags,
"idle");
}
(incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
(!incremental_marking()->weak_closure_was_overapproximated() &&
mark_compact_collector_.marking_deque()->IsEmpty() &&
- gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure(
+ gc_idle_time_handler_->ShouldDoOverApproximateWeakClosure(
static_cast<size_t>(idle_time_in_ms))))) {
OverApproximateWeakClosure(
"Idle notification: overapproximate weak closure");
return true;
} else if (incremental_marking()->IsComplete() ||
(mark_compact_collector_.marking_deque()->IsEmpty() &&
- gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
+ gc_idle_time_handler_->ShouldDoFinalIncrementalMarkCompact(
static_cast<size_t>(idle_time_in_ms), size_of_objects,
final_incremental_mark_compact_speed_in_bytes_per_ms))) {
CollectAllGarbage(current_gc_flags_,
}
-GCIdleTimeHandler::HeapState Heap::ComputeHeapState() {
- GCIdleTimeHandler::HeapState heap_state;
+GCIdleTimeHeapState Heap::ComputeHeapState() {
+ GCIdleTimeHeapState heap_state;
heap_state.contexts_disposed = contexts_disposed_;
heap_state.contexts_disposal_rate =
tracer()->ContextDisposalRateInMilliseconds();
bool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
- GCIdleTimeHandler::HeapState heap_state,
+ GCIdleTimeHeapState heap_state,
double deadline_in_ms) {
bool result = false;
switch (action.type) {
void Heap::IdleNotificationEpilogue(GCIdleTimeAction action,
- GCIdleTimeHandler::HeapState heap_state,
+ GCIdleTimeHeapState heap_state,
double start_ms, double deadline_in_ms) {
double idle_time_in_ms = deadline_in_ms - start_ms;
double current_time = MonotonicallyIncreasingTimeInMs();
tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(),
OldGenerationAllocationCounter());
- GCIdleTimeHandler::HeapState heap_state = ComputeHeapState();
+ GCIdleTimeHeapState heap_state = ComputeHeapState();
GCIdleTimeAction action =
- gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
+ gc_idle_time_handler_->Compute(idle_time_in_ms, heap_state);
bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms);
scavenge_collector_ = new Scavenger(this);
+ gc_idle_time_handler_ = new GCIdleTimeHandler();
+
memory_reducer_ = new MemoryReducer(this);
object_stats_ = new ObjectStats(this);
delete scavenge_collector_;
scavenge_collector_ = nullptr;
+ delete gc_idle_time_handler_;
+ gc_idle_time_handler_ = nullptr;
+
if (memory_reducer_ != nullptr) {
memory_reducer_->TearDown();
delete memory_reducer_;
#include "src/assert-scope.h"
#include "src/atomic-utils.h"
#include "src/globals.h"
-#include "src/heap/gc-idle-time-handler.h"
#include "src/heap/incremental-marking.h"
#include "src/heap/mark-compact.h"
#include "src/heap/spaces.h"
// Forward declarations.
class ArrayBufferTracker;
+class GCIdleTimeAction;
+class GCIdleTimeHandler;
+class GCIdleTimeHeapState;
+class GCTracer;
class HeapObjectsFilter;
class HeapStats;
class Isolate;
double idle_time_in_ms, size_t size_of_objects,
size_t mark_compact_speed_in_bytes_per_ms);
- GCIdleTimeHandler::HeapState ComputeHeapState();
+ GCIdleTimeHeapState ComputeHeapState();
bool PerformIdleTimeAction(GCIdleTimeAction action,
- GCIdleTimeHandler::HeapState heap_state,
+ GCIdleTimeHeapState heap_state,
double deadline_in_ms);
void IdleNotificationEpilogue(GCIdleTimeAction action,
- GCIdleTimeHandler::HeapState heap_state,
- double start_ms, double deadline_in_ms);
+ GCIdleTimeHeapState heap_state, double start_ms,
+ double deadline_in_ms);
void CheckAndNotifyBackgroundIdleNotification(double idle_time_in_ms,
double now_ms);
IncrementalMarking incremental_marking_;
- GCIdleTimeHandler gc_idle_time_handler_;
+ GCIdleTimeHandler* gc_idle_time_handler_;
MemoryReducer* memory_reducer_;
GCIdleTimeHandler* handler() { return &handler_; }
- GCIdleTimeHandler::HeapState DefaultHeapState() {
- GCIdleTimeHandler::HeapState result;
+ GCIdleTimeHeapState DefaultHeapState() {
+ GCIdleTimeHeapState result;
result.contexts_disposed = 0;
result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
result.incremental_marking_stopped = false;
TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
int idle_time_ms = 16;
EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
idle_time_ms, heap_state.new_space_capacity,
TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = kNewSpaceCapacity;
int idle_time_ms = 16;
EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = kNewSpaceCapacity;
heap_state.scavenge_speed_in_bytes_per_ms = 0;
int idle_time_ms = 8;
TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = kNewSpaceCapacity;
heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB;
int idle_time_ms = 16;
TEST_F(GCIdleTimeHandlerTest, DoScavengeLowAllocationRate) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = kNewSpaceCapacity;
heap_state.new_space_allocation_throughput_in_bytes_per_ms =
GCIdleTimeHandler::kLowAllocationThroughput - 1;
TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = kNewSpaceCapacity;
heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
int idle_time_ms = 16;
TEST_F(GCIdleTimeHandlerTest, DoNotScavengeSmallNewSpaceSize) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.used_new_space_size = (MB / 2) - 1;
heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
int idle_time_ms = 16;
TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 0;
TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate =
GCIdleTimeHandler::kHighContextDisposalRate - 1;
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate = 1.0;
heap_state.incremental_marking_stopped = true;
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate =
GCIdleTimeHandler::kHighContextDisposalRate;
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate =
GCIdleTimeHandler::kHighContextDisposalRate;
TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
double idle_time_ms = 10;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
TEST_F(GCIdleTimeHandlerTest, Scavenge) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
heap_state.used_new_space_size =
heap_state.new_space_capacity -
TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
heap_state.incremental_marking_stopped = true;
heap_state.used_new_space_size =
TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 10.0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
double idle_time_ms = 10.0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
for (int i = 0; i < kMaxNotifications; i++) {
GCIdleTimeAction action = handler()->Compute(0, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
for (int i = 0; i < kMaxNotifications; i++) {
GCIdleTimeAction action = handler()->Compute(10, heap_state);
TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
// Regression test for crbug.com/489323.
- GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+ GCIdleTimeHeapState heap_state = DefaultHeapState();
// Simulate incremental marking stopped and not eligible to start.
heap_state.incremental_marking_stopped = true;