for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+ // In this case we emulate incremental marking steps that finish with a
+ // full gc.
handler()->NotifyIdleMarkCompact();
}
+ heap_state.can_start_incremental_marking = false;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DONE, action.type);
}
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
if (action.type == DONE) break;
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+ // In this case we try to emulate incremental marking steps the finish with
+ // a full gc.
handler()->NotifyIdleMarkCompact();
}
+ heap_state.can_start_incremental_marking = false;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DONE, action.type);
// Emulate mutator work.
for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
handler()->NotifyScavenge();
}
+ heap_state.can_start_incremental_marking = true;
action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
return GCIdleTimeAction::Done();
}
}
+
if (heap_state.incremental_marking_stopped) {
size_t estimated_time_in_ms =
EstimateMarkCompactTime(heap_state.size_of_objects,
// can get rid of this special case and always start incremental marking.
int remaining_mark_sweeps =
kMaxMarkCompactsInIdleRound - mark_compacts_since_idle_round_started_;
- if (heap_state.contexts_disposed > 0 || remaining_mark_sweeps <= 2 ||
- !heap_state.can_start_incremental_marking) {
+ if (heap_state.contexts_disposed > 0 ||
+ (idle_time_in_ms > kMaxFrameRenderingIdleTime &&
+ (remaining_mark_sweeps <= 2 ||
+ !heap_state.can_start_incremental_marking))) {
return GCIdleTimeAction::FullGC();
}
}
return GCIdleTimeAction::FinalizeSweeping();
}
+ if (heap_state.incremental_marking_stopped &&
+ !heap_state.can_start_incremental_marking) {
+ return GCIdleTimeAction::Nothing();
+ }
size_t step_size = EstimateMarkingStepSize(
idle_time_in_ms, heap_state.incremental_marking_speed_in_bytes_per_ms);
return GCIdleTimeAction::IncrementalMarking(step_size);
// step.
static const size_t kSmallHeapSize = 2 * kPointerSize * MB;
+ // That is the maximum idle time we will have during frame rendering.
+ static const size_t kMaxFrameRenderingIdleTime = 16;
+
struct HeapState {
int contexts_disposed;
size_t size_of_objects;
LOG(isolate_, ResourceEvent("scavenge", "end"));
gc_state_ = NOT_IN_GC;
-
- gc_idle_time_handler_.NotifyScavenge();
}
heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
// TODO(ulan): Start incremental marking only for large heaps.
- heap_state.can_start_incremental_marking = true;
+ heap_state.can_start_incremental_marking =
+ incremental_marking()->ShouldActivate();
heap_state.sweeping_in_progress =
mark_compact_collector()->sweeping_in_progress();
heap_state.mark_compact_speed_in_bytes_per_ms =
}
+bool IncrementalMarking::ShouldActivate() {
+ return WorthActivating() && heap_->NextGCIsLikelyToBeFull();
+}
+
+
bool IncrementalMarking::WorthActivating() {
#ifndef DEBUG
static const intptr_t kActivationThreshold = 8 * MB;
void IncrementalMarking::OldSpaceStep(intptr_t allocated) {
- if (IsStopped() && WorthActivating() && heap_->NextGCIsLikelyToBeFull()) {
+ if (IsStopped() && ShouldActivate()) {
// TODO(hpayer): Let's play safe for now, but compaction should be
// in principle possible.
Start(PREVENT_COMPACTION);
bool WorthActivating();
+ bool ShouldActivate();
+
enum CompactionFlag { ALLOW_COMPACTION, PREVENT_COMPACTION };
void Start(CompactionFlag flag = ALLOW_COMPACTION);
TEST(Regress2107) {
const intptr_t MB = 1024 * 1024;
- const int kShortIdlePauseInMs = 100;
- const int kLongIdlePauseInMs = 1000;
+ const int kIdlePauseInMs = 1000;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(env->GetIsolate());
intptr_t initial_size = CcTest::heap()->SizeOfObjects();
// Send idle notification to start a round of incremental GCs.
- env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
+ env->GetIsolate()->IdleNotification(kIdlePauseInMs);
// Emulate 7 page reloads.
for (int i = 0; i < 7; i++) {
{
ctx->Exit();
}
env->GetIsolate()->ContextDisposedNotification();
- env->GetIsolate()->IdleNotification(kLongIdlePauseInMs);
+ env->GetIsolate()->IdleNotification(kIdlePauseInMs);
}
// Create garbage and check that idle notification still collects it.
CreateGarbageInOldSpace();
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(kIdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK_LT(final_size, initial_size + 1);