Reviewers: ulan,
Message:
adding tests...
Description:
Check if there is still time before finalizing an incremental collection.
BUG=
Please review this at https://codereview.chromium.org/629903003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+77, -14 lines):
M src/heap/gc-idle-time-handler.h
M src/heap/gc-idle-time-handler.cc
M src/heap/heap.h
M src/heap/heap.cc
M src/heap/incremental-marking.h
M src/heap/incremental-marking.cc
M src/heap/mark-compact.h
M src/heap/mark-compact.cc
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
3e3644956b15956239feef2bb06117786089ee62..5c46842e22f17fd04bd4e50a8a6b0ca927f02e2f
100644
--- a/src/heap/gc-idle-time-handler.cc
+++ b/src/heap/gc-idle-time-handler.cc
@@ -63,6 +63,9 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize(
size_t GCIdleTimeHandler::EstimateMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) {
+ // TODO(hpayer): Be more precise about the type of mark-compact event. It
+ // makes a huge difference if it is incremental or non-incremental and if
+ // compaction is happening.
if (mark_compact_speed_in_bytes_per_ms == 0) {
mark_compact_speed_in_bytes_per_ms =
kInitialConservativeMarkCompactSpeed;
}
@@ -110,6 +113,15 @@ bool GCIdleTimeHandler::DoScavenge(
}
+bool GCIdleTimeHandler::DoMarkCompact(
+ size_t idle_time_in_ms, size_t size_of_objects,
+ size_t mark_compact_speed_in_bytes_per_ms) {
+ return idle_time_in_ms >=
+ EstimateMarkCompactTime(size_of_objects,
+ mark_compact_speed_in_bytes_per_ms);
+}
+
+
// The following logic is implemented by the controller:
// (1) If the new space is almost full and we can affort a Scavenge or if
the
// next Scavenge will very likely take long, then a Scavenge is performed.
@@ -148,10 +160,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t
idle_time_in_ms,
}
if (heap_state.incremental_marking_stopped) {
- size_t estimated_time_in_ms =
- EstimateMarkCompactTime(heap_state.size_of_objects,
-
heap_state.mark_compact_speed_in_bytes_per_ms);
- if (idle_time_in_ms >= estimated_time_in_ms ||
+ if (DoMarkCompact(idle_time_in_ms, heap_state.size_of_objects,
+ heap_state.mark_compact_speed_in_bytes_per_ms) ||
(heap_state.size_of_objects < kSmallHeapSize &&
heap_state.contexts_disposed > 0)) {
// If there are no more than two GCs left in this idle round and we
are
Index: src/heap/gc-idle-time-handler.h
diff --git a/src/heap/gc-idle-time-handler.h
b/src/heap/gc-idle-time-handler.h
index
15aaea668f8e98047e78176642d5d2d2667adc04..3f6f9c76249a874b235af36213d3ef974102f024
100644
--- a/src/heap/gc-idle-time-handler.h
+++ b/src/heap/gc-idle-time-handler.h
@@ -155,6 +155,9 @@ class GCIdleTimeHandler {
static size_t EstimateMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
+ static bool DoMarkCompact(size_t idle_time_in_ms, size_t size_of_objects,
+ size_t mark_compact_speed_in_bytes_per_ms);
+
static bool DoScavenge(
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,
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index
0ccd0ab2f2b86ddab87573070841954d5f53c548..8bc55e3c946266059e16ef6e77e55db1658f44da
100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -4267,11 +4267,14 @@ void Heap::MakeHeapIterable() {
}
-void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
- incremental_marking()->Step(step_size,
- IncrementalMarking::NO_GC_VIA_STACK_GUARD,
true);
-
- if (incremental_marking()->IsComplete()) {
+void Heap::TryFinalizeIdleIncrementalMarking(
+ size_t idle_time_in_ms, size_t size_of_objects,
+ size_t mark_compact_speed_in_bytes_per_ms) {
+ if (incremental_marking()->IsComplete() ||
+ (mark_compact_collector()->IsMarkingDequeEmpty() &&
+ gc_idle_time_handler_.DoMarkCompact(
+ idle_time_in_ms, size_of_objects,
+ mark_compact_speed_in_bytes_per_ms))) {
bool uncommit = false;
if (gc_count_at_last_idle_gc_ == gc_count_) {
// No GC since the last full GC, the mutator is probably not active.
@@ -4339,7 +4342,12 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
if (incremental_marking()->IsStopped()) {
incremental_marking()->Start();
}
- AdvanceIdleIncrementalMarking(action.parameter);
+ incremental_marking()->Step(action.parameter,
+
IncrementalMarking::NO_GC_VIA_STACK_GUARD,
+ true, false);
+ TryFinalizeIdleIncrementalMarking(
+ idle_time_in_ms, heap_state.size_of_objects,
+ heap_state.mark_compact_speed_in_bytes_per_ms);
break;
case DO_FULL_GC: {
HistogramTimerScope scope(isolate_->counters()->gc_context());
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index
c37464c9bcd6e9cc5c2fbf34347cc68b2cff4398..13187118e76b3d55fd74362cf315959a50b7f83f
100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -1940,7 +1940,9 @@ class Heap {
void SelectScavengingVisitorsTable();
- void AdvanceIdleIncrementalMarking(intptr_t step_size);
+ void TryFinalizeIdleIncrementalMarking(
+ size_t idle_time_in_ms, size_t size_of_objects,
+ size_t mark_compact_speed_in_bytes_per_ms);
bool WorthActivatingIncrementalMarking();
Index: src/heap/incremental-marking.cc
diff --git a/src/heap/incremental-marking.cc
b/src/heap/incremental-marking.cc
index
d72423a60aa81619516404c2995ebc26df4e60a2..c3f60f4bc66950f6ffbdc533b2a6b56bd5a953c6
100644
--- a/src/heap/incremental-marking.cc
+++ b/src/heap/incremental-marking.cc
@@ -27,6 +27,7 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
should_hurry_(false),
marking_speed_(0),
allocated_(0),
+ idle_marking_delay_counter_(0),
no_marking_scope_depth_(0),
unscanned_bytes_of_large_object_(0) {}
@@ -893,7 +894,7 @@ void IncrementalMarking::SpeedUp() {
void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction
action,
- bool force_marking) {
+ bool force_marking, bool force_completion) {
if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking ||
!FLAG_incremental_marking_steps ||
(state_ != SWEEPING && state_ != MARKING)) {
@@ -943,7 +944,11 @@ void IncrementalMarking::Step(intptr_t
allocated_bytes, CompletionAction action,
}
} else if (state_ == MARKING) {
bytes_processed = ProcessMarkingDeque(bytes_to_process);
- if (marking_deque_.IsEmpty()) MarkingComplete(action);
+ IncrementIdleMarkingDelayCounter();
+ if (marking_deque_.IsEmpty() &&
+ (force_completion || IsIdleMarkingDelayCounterLimitReached())) {
+ MarkingComplete(action);
+ }
}
steps_count_++;
@@ -978,5 +983,20 @@ void IncrementalMarking::ResetStepCounters() {
int64_t IncrementalMarking::SpaceLeftInOldSpace() {
return heap_->MaxOldGenerationSize() -
heap_->PromotedSpaceSizeOfObjects();
}
+
+
+bool IncrementalMarking::IsIdleMarkingDelayCounterLimitReached() {
+ return idle_marking_delay_counter_ >= kMaxIdleMarkingDelayCounter;
+}
+
+
+void IncrementalMarking::IncrementIdleMarkingDelayCounter() {
+ idle_marking_delay_counter_++;
+}
+
+
+void IncrementalMarking::ClearIdleMarkingDelayCounter() {
+ idle_marking_delay_counter_ = 0;
+}
}
} // namespace v8::internal
Index: src/heap/incremental-marking.h
diff --git a/src/heap/incremental-marking.h b/src/heap/incremental-marking.h
index
e4a8e972ca8fb10a08073a9dd8bf0fdb6efcdb03..434b73f12b85b2727cb1779cfd36ce5de2207171
100644
--- a/src/heap/incremental-marking.h
+++ b/src/heap/incremental-marking.h
@@ -83,10 +83,14 @@ class IncrementalMarking {
static const intptr_t kMarkingSpeedAccelleration = 2;
static const intptr_t kMaxMarkingSpeed = 1000;
+ // This is the upper bound for how many times we allow finalization of
+ // incremental marking to be postponed.
+ static const size_t kMaxIdleMarkingDelayCounter = 3;
+
void OldSpaceStep(intptr_t allocated);
void Step(intptr_t allocated, CompletionAction action,
- bool force_marking = false);
+ bool force_marking = false, bool force_completion = true);
inline void RestartIfNotMarking() {
if (state_ == COMPLETE) {
@@ -165,6 +169,8 @@ class IncrementalMarking {
unscanned_bytes_of_large_object_ = unscanned_bytes;
}
+ void ClearIdleMarkingDelayCounter();
+
private:
int64_t SpaceLeftInOldSpace();
@@ -195,6 +201,10 @@ class IncrementalMarking {
INLINE(void VisitObject(Map* map, HeapObject* obj, int size));
+ bool IsIdleMarkingDelayCounterLimitReached();
+
+ void IncrementIdleMarkingDelayCounter();
+
Heap* heap_;
State state_;
@@ -213,6 +223,7 @@ class IncrementalMarking {
intptr_t bytes_scanned_;
intptr_t allocated_;
intptr_t write_barriers_invoked_since_last_step_;
+ size_t idle_marking_delay_counter_;
int no_marking_scope_depth_;
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index
69fc579e2fe65ec359644efd01362e5bea362d61..da3ef1e0991fffe02431fb776ece61057811ac4f
100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -965,6 +965,8 @@ void MarkCompactCollector::Finish() {
Deoptimizer::DeoptimizeMarkedCode(isolate());
have_code_to_deoptimize_ = false;
}
+
+ heap_->incremental_marking()->ClearIdleMarkingDelayCounter();
}
@@ -2040,6 +2042,11 @@ void
MarkCompactCollector::MarkAllocationSite(AllocationSite* site) {
}
+bool MarkCompactCollector::IsMarkingDequeEmpty() {
+ return marking_deque_.IsEmpty();
+}
+
+
void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
// Mark the heap roots including global variables, stack variables,
// etc., and all objects reachable from them.
Index: src/heap/mark-compact.h
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index
5e615b306ef8b8cab0dd2793313f3ae64b7ba9c7..d56881f7a80b21d655dd9ce61c9345365c2ed484
100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -657,6 +657,8 @@ class MarkCompactCollector {
// to artificially keep AllocationSites alive for a time.
void MarkAllocationSite(AllocationSite* site);
+ bool IsMarkingDequeEmpty();
+
private:
class SweeperTask;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.