| Index: src/heap/gc-idle-time-handler.cc
|
| diff --git a/src/heap/gc-idle-time-handler.cc b/src/heap/gc-idle-time-handler.cc
|
| index 5ff4017c233f071b742974b9fcf242609de03de3..a2e08b28c514e1c08c0c394a9100c8da6150897d 100644
|
| --- a/src/heap/gc-idle-time-handler.cc
|
| +++ b/src/heap/gc-idle-time-handler.cc
|
| @@ -3,12 +3,14 @@
|
| // found in the LICENSE file.
|
|
|
| #include "src/heap/gc-idle-time-handler.h"
|
| +#include "src/heap/gc-tracer.h"
|
| +#include "src/utils.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -
|
| const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
|
| +const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000000;
|
|
|
|
|
| size_t GCIdleTimeHandler::EstimateMarkingStepSize(
|
| @@ -16,14 +18,13 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize(
|
| DCHECK(idle_time_in_ms > 0);
|
|
|
| if (marking_speed_in_bytes_per_ms == 0) {
|
| - marking_speed_in_bytes_per_ms =
|
| - GCIdleTimeHandler::kInitialConservativeMarkingSpeed;
|
| + marking_speed_in_bytes_per_ms = kInitialConservativeMarkingSpeed;
|
| }
|
|
|
| size_t marking_step_size = marking_speed_in_bytes_per_ms * idle_time_in_ms;
|
| if (marking_step_size / marking_speed_in_bytes_per_ms != idle_time_in_ms) {
|
| // In the case of an overflow we return maximum marking step size.
|
| - return GCIdleTimeHandler::kMaximumMarkingStepSize;
|
| + return kMaximumMarkingStepSize;
|
| }
|
|
|
| if (marking_step_size > kMaximumMarkingStepSize)
|
| @@ -32,5 +33,51 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize(
|
| return static_cast<size_t>(marking_step_size *
|
| GCIdleTimeHandler::kConservativeTimeRatio);
|
| }
|
| +
|
| +
|
| +size_t GCIdleTimeHandler::EstimateMarkCompactTime(
|
| + size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) {
|
| + if (mark_compact_speed_in_bytes_per_ms == 0) {
|
| + mark_compact_speed_in_bytes_per_ms = kInitialConservativeMarkCompactSpeed;
|
| + }
|
| + size_t result = size_of_objects / mark_compact_speed_in_bytes_per_ms;
|
| + return Min(result, kMaxMarkCompactTimeInMs);
|
| +}
|
| +
|
| +
|
| +GCIdleTimeAction GCIdleTimeHandler::Compute(int idle_time_in_ms,
|
| + int contexts_disposed,
|
| + size_t size_of_objects,
|
| + bool incremental_marking_stopped,
|
| + GCTracer* gc_tracer) {
|
| + if (IsIdleRoundFinished()) {
|
| + if (EnoughGarbageSinceLastIdleRound() || contexts_disposed > 0) {
|
| + StartIdleRound();
|
| + } else {
|
| + return GCIdleTimeAction::Nothing();
|
| + }
|
| + }
|
| + if (incremental_marking_stopped) {
|
| + size_t speed =
|
| + static_cast<size_t>(gc_tracer->MarkCompactSpeedInBytesPerMillisecond());
|
| + if (idle_time_in_ms >=
|
| + static_cast<int>(EstimateMarkCompactTime(size_of_objects, speed))) {
|
| + // 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
|
| + // the code space.
|
| + // TODO(ulan): Once we enable code compaction for incremental marking, we
|
| + // can get rid of this special case and always start incremental marking.
|
| + int remaining_mark_sweeps =
|
| + kMaxMarkCompactsInIdleRound - mark_compacts_since_idle_round_started_;
|
| + if (contexts_disposed > 0 || remaining_mark_sweeps <= 2) {
|
| + return GCIdleTimeAction::FullGC();
|
| + }
|
| + }
|
| + }
|
| + intptr_t speed = gc_tracer->IncrementalMarkingSpeedInBytesPerMillisecond();
|
| + size_t step_size =
|
| + static_cast<size_t>(EstimateMarkingStepSize(idle_time_in_ms, speed));
|
| + return GCIdleTimeAction::IncrementalMarking(step_size);
|
| +}
|
| }
|
| }
|
|
|