Commit 297935b3 authored by hpayer's avatar hpayer Committed by Commit bot

Use deadline in IdleNotification.

BUG=417668
LOG=n

Review URL: https://codereview.chromium.org/750813003

Cr-Commit-Position: refs/heads/master@{#25560}
parent e42fda5e
...@@ -5063,17 +5063,23 @@ class V8_EXPORT Isolate { ...@@ -5063,17 +5063,23 @@ class V8_EXPORT Isolate {
/** /**
* Optional notification that the embedder is idle. * Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint. * V8 uses the notification to perform garbage collection.
* This call can be used repeatedly if the embedder remains idle. * This call can be used repeatedly if the embedder remains idle.
* Returns true if the embedder should stop calling IdleNotification * Returns true if the embedder should stop calling IdleNotification
* until real work has been done. This indicates that V8 has done * until real work has been done. This indicates that V8 has done
* as much cleanup as it will be able to do. * as much cleanup as it will be able to do.
* *
* The idle_time_in_ms argument specifies the time V8 has to do reduce * The idle_time_in_ms argument specifies the time V8 has to perform
* the memory footprint. There is no guarantee that the actual work will be * garbage collection. There is no guarantee that the actual work will be
* done within the time limit. * done within the time limit.
* The deadline_in_seconds argument specifies the deadline V8 has to finish
* garbage collection work. deadline_in_seconds is compared with
* MonotonicallyIncreasingTime() and should be based on the same timebase as
* that function. There is no guarantee that the actual work will be done
* within the time limit.
*/ */
bool IdleNotification(int idle_time_in_ms); bool IdleNotification(int idle_time_in_ms);
bool IdleNotificationDeadline(double deadline_in_seconds);
/** /**
* Optional notification that the system is running low on memory. * Optional notification that the system is running low on memory.
......
...@@ -6650,6 +6650,15 @@ bool Isolate::IdleNotification(int idle_time_in_ms) { ...@@ -6650,6 +6650,15 @@ bool Isolate::IdleNotification(int idle_time_in_ms) {
} }
bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
// Returning true tells the caller that it need not
// continue to call IdleNotification.
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
if (!i::FLAG_use_idle_notification) return true;
return isolate->heap()->IdleNotification(deadline_in_seconds);
}
void Isolate::LowMemoryNotification() { void Isolate::LowMemoryNotification() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
{ {
......
...@@ -189,9 +189,9 @@ bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( ...@@ -189,9 +189,9 @@ bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
// request, we finalize sweeping here. // request, we finalize sweeping here.
// (6) If incremental marking is in progress, we perform a marking step. Note, // (6) If incremental marking is in progress, we perform a marking step. Note,
// that this currently may trigger a full garbage collection. // that this currently may trigger a full garbage collection.
GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
HeapState heap_state) { HeapState heap_state) {
if (idle_time_in_ms == 0) { if (idle_time_in_ms <= 0.0) {
if (heap_state.incremental_marking_stopped) { if (heap_state.incremental_marking_stopped) {
if (ShouldDoContextDisposalMarkCompact( if (ShouldDoContextDisposalMarkCompact(
heap_state.contexts_disposed, heap_state.contexts_disposed,
...@@ -203,7 +203,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, ...@@ -203,7 +203,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
} }
if (ShouldDoScavenge( if (ShouldDoScavenge(
idle_time_in_ms, heap_state.new_space_capacity, static_cast<size_t>(idle_time_in_ms), heap_state.new_space_capacity,
heap_state.used_new_space_size, heap_state.used_new_space_size,
heap_state.scavenge_speed_in_bytes_per_ms, heap_state.scavenge_speed_in_bytes_per_ms,
heap_state.new_space_allocation_throughput_in_bytes_per_ms)) { heap_state.new_space_allocation_throughput_in_bytes_per_ms)) {
...@@ -219,7 +219,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, ...@@ -219,7 +219,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
} }
if (heap_state.incremental_marking_stopped) { if (heap_state.incremental_marking_stopped) {
if (ShouldDoMarkCompact(idle_time_in_ms, heap_state.size_of_objects, if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms),
heap_state.size_of_objects,
heap_state.mark_compact_speed_in_bytes_per_ms)) { heap_state.mark_compact_speed_in_bytes_per_ms)) {
// If there are no more than two GCs left in this idle round and we are // If there are no more than two GCs left in this idle round and we are
// allowed to do a full GC, then make those GCs full in order to compact // allowed to do a full GC, then make those GCs full in order to compact
...@@ -228,7 +229,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, ...@@ -228,7 +229,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
// can get rid of this special case and always start incremental marking. // can get rid of this special case and always start incremental marking.
int remaining_mark_sweeps = int remaining_mark_sweeps =
kMaxMarkCompactsInIdleRound - mark_compacts_since_idle_round_started_; kMaxMarkCompactsInIdleRound - mark_compacts_since_idle_round_started_;
if (idle_time_in_ms > kMaxFrameRenderingIdleTime && if (static_cast<size_t>(idle_time_in_ms) > kMaxFrameRenderingIdleTime &&
(remaining_mark_sweeps <= 2 || (remaining_mark_sweeps <= 2 ||
!heap_state.can_start_incremental_marking)) { !heap_state.can_start_incremental_marking)) {
return GCIdleTimeAction::FullGC(); return GCIdleTimeAction::FullGC();
...@@ -240,7 +241,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, ...@@ -240,7 +241,7 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
} }
// TODO(hpayer): Estimate finalize sweeping time. // TODO(hpayer): Estimate finalize sweeping time.
if (heap_state.sweeping_in_progress && if (heap_state.sweeping_in_progress &&
idle_time_in_ms >= kMinTimeForFinalizeSweeping) { static_cast<size_t>(idle_time_in_ms) >= kMinTimeForFinalizeSweeping) {
return GCIdleTimeAction::FinalizeSweeping(); return GCIdleTimeAction::FinalizeSweeping();
} }
...@@ -249,7 +250,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms, ...@@ -249,7 +250,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
return GCIdleTimeAction::Nothing(); return GCIdleTimeAction::Nothing();
} }
size_t step_size = EstimateMarkingStepSize( size_t step_size = EstimateMarkingStepSize(
idle_time_in_ms, heap_state.incremental_marking_speed_in_bytes_per_ms); static_cast<size_t>(idle_time_in_ms),
heap_state.incremental_marking_speed_in_bytes_per_ms);
return GCIdleTimeAction::IncrementalMarking(step_size); return GCIdleTimeAction::IncrementalMarking(step_size);
} }
} }
......
...@@ -148,7 +148,7 @@ class GCIdleTimeHandler { ...@@ -148,7 +148,7 @@ class GCIdleTimeHandler {
: mark_compacts_since_idle_round_started_(0), : mark_compacts_since_idle_round_started_(0),
scavenges_since_last_idle_round_(0) {} scavenges_since_last_idle_round_(0) {}
GCIdleTimeAction Compute(size_t idle_time_in_ms, HeapState heap_state); GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
void NotifyIdleMarkCompact() { void NotifyIdleMarkCompact() {
if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) { if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
......
...@@ -4386,12 +4386,12 @@ void Heap::IdleMarkCompact(const char* message) { ...@@ -4386,12 +4386,12 @@ void Heap::IdleMarkCompact(const char* message) {
void Heap::TryFinalizeIdleIncrementalMarking( void Heap::TryFinalizeIdleIncrementalMarking(
size_t idle_time_in_ms, size_t size_of_objects, double idle_time_in_ms, size_t size_of_objects,
size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
if (incremental_marking()->IsComplete() || if (incremental_marking()->IsComplete() ||
(mark_compact_collector()->IsMarkingDequeEmpty() && (mark_compact_collector()->IsMarkingDequeEmpty() &&
gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
idle_time_in_ms, size_of_objects, static_cast<size_t>(idle_time_in_ms), size_of_objects,
final_incremental_mark_compact_speed_in_bytes_per_ms))) { final_incremental_mark_compact_speed_in_bytes_per_ms))) {
CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
} }
...@@ -4404,11 +4404,24 @@ bool Heap::WorthActivatingIncrementalMarking() { ...@@ -4404,11 +4404,24 @@ bool Heap::WorthActivatingIncrementalMarking() {
} }
static double MonotonicallyIncreasingTimeInMs() {
return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
static_cast<double>(base::Time::kMillisecondsPerSecond);
}
bool Heap::IdleNotification(int idle_time_in_ms) { bool Heap::IdleNotification(int idle_time_in_ms) {
base::ElapsedTimer timer; return IdleNotification(
timer.Start(); V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( (static_cast<double>(idle_time_in_ms) /
idle_time_in_ms); static_cast<double>(base::Time::kMillisecondsPerSecond)));
}
bool Heap::IdleNotification(double deadline_in_seconds) {
double deadline_in_ms =
deadline_in_seconds *
static_cast<double>(base::Time::kMillisecondsPerSecond);
HistogramTimerScope idle_notification_scope( HistogramTimerScope idle_notification_scope(
isolate_->counters()->gc_idle_notification()); isolate_->counters()->gc_idle_notification());
...@@ -4438,11 +4451,13 @@ bool Heap::IdleNotification(int idle_time_in_ms) { ...@@ -4438,11 +4451,13 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
static_cast<size_t>( static_cast<size_t>(
tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
GCIdleTimeAction action = GCIdleTimeAction action =
gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
static_cast<int>(idle_time_in_ms));
bool result = false; bool result = false;
int actual_time_in_ms = 0;
switch (action.type) { switch (action.type) {
case DONE: case DONE:
result = true; result = true;
...@@ -4455,9 +4470,9 @@ bool Heap::IdleNotification(int idle_time_in_ms) { ...@@ -4455,9 +4470,9 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
IncrementalMarking::NO_GC_VIA_STACK_GUARD, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
IncrementalMarking::FORCE_MARKING, IncrementalMarking::FORCE_MARKING,
IncrementalMarking::DO_NOT_FORCE_COMPLETION); IncrementalMarking::DO_NOT_FORCE_COMPLETION);
actual_time_in_ms = static_cast<int>(timer.Elapsed().InMilliseconds()); double remaining_idle_time_in_ms =
int remaining_idle_time_in_ms = idle_time_in_ms - actual_time_in_ms; deadline_in_ms - MonotonicallyIncreasingTimeInMs();
if (remaining_idle_time_in_ms > 0) { if (remaining_idle_time_in_ms > 0.0) {
TryFinalizeIdleIncrementalMarking( TryFinalizeIdleIncrementalMarking(
remaining_idle_time_in_ms, heap_state.size_of_objects, remaining_idle_time_in_ms, heap_state.size_of_objects,
heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms);
...@@ -4485,21 +4500,25 @@ bool Heap::IdleNotification(int idle_time_in_ms) { ...@@ -4485,21 +4500,25 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
break; break;
} }
actual_time_in_ms = static_cast<int>(timer.Elapsed().InMilliseconds()); double current_time = MonotonicallyIncreasingTimeInMs();
if (actual_time_in_ms <= idle_time_in_ms) { double deadline_difference = deadline_in_ms - current_time;
if (deadline_difference >= 0) {
if (action.type != DONE && action.type != DO_NOTHING) { if (action.type != DONE && action.type != DO_NOTHING) {
isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
idle_time_in_ms - actual_time_in_ms); static_cast<int>(deadline_difference));
} }
} else { } else {
isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( isolate()->counters()->gc_idle_time_limit_overshot()->AddSample(
actual_time_in_ms - idle_time_in_ms); static_cast<int>(-deadline_difference));
} }
if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) || if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) ||
FLAG_trace_idle_notification_verbose) { FLAG_trace_idle_notification_verbose) {
PrintF("Idle notification: requested idle time %d ms, actual time %d ms [", PrintF(
idle_time_in_ms, actual_time_in_ms); "Idle notification: requested idle time %.2f ms, used idle time %.2f "
"ms, deadline usage %.2f ms [",
idle_time_in_ms, current_time, deadline_difference);
action.Print(); action.Print();
PrintF("]"); PrintF("]");
if (FLAG_trace_idle_notification_verbose) { if (FLAG_trace_idle_notification_verbose) {
......
...@@ -1104,6 +1104,7 @@ class Heap { ...@@ -1104,6 +1104,7 @@ class Heap {
void DisableInlineAllocation(); void DisableInlineAllocation();
// Implements the corresponding V8 API function. // Implements the corresponding V8 API function.
bool IdleNotification(double deadline_in_seconds);
bool IdleNotification(int idle_time_in_ms); bool IdleNotification(int idle_time_in_ms);
// Declare all the root indices. This defines the root list order. // Declare all the root indices. This defines the root list order.
...@@ -2008,7 +2009,7 @@ class Heap { ...@@ -2008,7 +2009,7 @@ class Heap {
void IdleMarkCompact(const char* message); void IdleMarkCompact(const char* message);
void TryFinalizeIdleIncrementalMarking( void TryFinalizeIdleIncrementalMarking(
size_t idle_time_in_ms, size_t size_of_objects, double idle_time_in_ms, size_t size_of_objects,
size_t mark_compact_speed_in_bytes_per_ms); size_t mark_compact_speed_in_bytes_per_ms);
bool WorthActivatingIncrementalMarking(); bool WorthActivatingIncrementalMarking();
......
...@@ -198,7 +198,7 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { ...@@ -198,7 +198,7 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1; heap_state.contexts_disposed = 1;
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
int idle_time_ms = 0; double idle_time_ms = 0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type); EXPECT_EQ(DO_NOTHING, action.type);
} }
...@@ -210,7 +210,7 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { ...@@ -210,7 +210,7 @@ TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
heap_state.contexts_disposal_rate = heap_state.contexts_disposal_rate =
GCIdleTimeHandler::kHighContextDisposalRate - 1; GCIdleTimeHandler::kHighContextDisposalRate - 1;
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
int idle_time_ms = 0; double idle_time_ms = 0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type); EXPECT_EQ(DO_FULL_GC, action.type);
} }
...@@ -223,8 +223,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) { ...@@ -223,8 +223,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false; heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = double idle_time_ms =
static_cast<int>((heap_state.size_of_objects + speed - 1) / speed); static_cast<double>((heap_state.size_of_objects + speed - 1) / speed);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type); EXPECT_EQ(DO_FULL_GC, action.type);
} }
...@@ -235,7 +235,7 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { ...@@ -235,7 +235,7 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
heap_state.contexts_disposed = 1; heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate = 1.0; heap_state.contexts_disposal_rate = 1.0;
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
int idle_time_ms = 0; double idle_time_ms = 0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type); EXPECT_EQ(DO_FULL_GC, action.type);
} }
...@@ -247,7 +247,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { ...@@ -247,7 +247,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
heap_state.contexts_disposal_rate = 1.0; heap_state.contexts_disposal_rate = 1.0;
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1); double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
} }
...@@ -258,7 +259,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { ...@@ -258,7 +259,8 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
heap_state.contexts_disposed = 1; heap_state.contexts_disposed = 1;
heap_state.contexts_disposal_rate = 1.0; heap_state.contexts_disposal_rate = 1.0;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1); double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
} }
...@@ -267,7 +269,7 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { ...@@ -267,7 +269,7 @@ TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
int idle_time_ms = 10; double idle_time_ms = 10;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
...@@ -280,7 +282,7 @@ TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { ...@@ -280,7 +282,7 @@ TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
int idle_time_ms = 10; double idle_time_ms = 10;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
...@@ -294,7 +296,8 @@ TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { ...@@ -294,7 +296,8 @@ TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false; heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1); double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed - 1);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type); EXPECT_EQ(DO_NOTHING, action.type);
} }
...@@ -305,7 +308,8 @@ TEST_F(GCIdleTimeHandlerTest, StopEventually1) { ...@@ -305,7 +308,8 @@ TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false; heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1); double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed + 1);
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type); EXPECT_EQ(DO_FULL_GC, action.type);
...@@ -318,7 +322,7 @@ TEST_F(GCIdleTimeHandlerTest, StopEventually1) { ...@@ -318,7 +322,7 @@ TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
TEST_F(GCIdleTimeHandlerTest, StopEventually2) { TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10; double idle_time_ms = 10;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
...@@ -337,7 +341,8 @@ TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) { ...@@ -337,7 +341,8 @@ TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
heap_state.incremental_marking_stopped = true; heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false; heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1); double idle_time_ms =
static_cast<double>(heap_state.size_of_objects / speed + 1);
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type); EXPECT_EQ(DO_FULL_GC, action.type);
...@@ -356,7 +361,7 @@ TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) { ...@@ -356,7 +361,7 @@ TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) { TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10; double idle_time_ms = 10;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
if (action.type == DONE) break; if (action.type == DONE) break;
...@@ -384,7 +389,8 @@ TEST_F(GCIdleTimeHandlerTest, Scavenge) { ...@@ -384,7 +389,8 @@ TEST_F(GCIdleTimeHandlerTest, Scavenge) {
heap_state.used_new_space_size = heap_state.used_new_space_size =
heap_state.new_space_capacity - heap_state.new_space_capacity -
(kNewSpaceAllocationThroughput * idle_time_ms); (kNewSpaceAllocationThroughput * idle_time_ms);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action =
handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
EXPECT_EQ(DO_SCAVENGE, action.type); EXPECT_EQ(DO_SCAVENGE, action.type);
} }
...@@ -397,17 +403,18 @@ TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) { ...@@ -397,17 +403,18 @@ TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
heap_state.used_new_space_size = heap_state.used_new_space_size =
heap_state.new_space_capacity - heap_state.new_space_capacity -
(kNewSpaceAllocationThroughput * idle_time_ms); (kNewSpaceAllocationThroughput * idle_time_ms);
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action =
handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
EXPECT_EQ(DO_SCAVENGE, action.type); EXPECT_EQ(DO_SCAVENGE, action.type);
heap_state.used_new_space_size = 0; heap_state.used_new_space_size = 0;
action = handler()->Compute(idle_time_ms, heap_state); action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
EXPECT_EQ(DO_NOTHING, action.type); EXPECT_EQ(DO_NOTHING, action.type);
} }
TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 0; double idle_time_ms = 0;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type); EXPECT_EQ(DO_NOTHING, action.type);
} }
...@@ -415,7 +422,7 @@ TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { ...@@ -415,7 +422,7 @@ TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) { TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10; double idle_time_ms = 10;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
if (action.type == DONE) break; if (action.type == DONE) break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment