Revision: 23979
Author: [email protected]
Date: Tue Sep 16 13:00:05 2014 UTC
Log: Allow IdleNotification to trigger Scavenges.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/563493002
https://code.google.com/p/v8/source/detail?r=23979
Modified:
/branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc
/branches/bleeding_edge/src/heap/gc-idle-time-handler.cc
/branches/bleeding_edge/src/heap/gc-idle-time-handler.h
/branches/bleeding_edge/src/heap/heap.cc
/branches/bleeding_edge/src/heap/spaces.h
=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc Tue
Sep 16 12:48:59 2014 UTC
+++ /branches/bleeding_edge/src/heap/gc-idle-time-handler-unittest.cc Tue
Sep 16 13:00:05 2014 UTC
@@ -28,12 +28,17 @@
result.sweeping_in_progress = false;
result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
+ result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
+ result.available_new_space_memory = kNewSpaceCapacity;
+ result.new_space_capacity = kNewSpaceCapacity;
return result;
}
static const size_t kSizeOfObjects = 100 * MB;
static const size_t kMarkCompactSpeed = 200 * KB;
static const size_t kMarkingSpeed = 200 * KB;
+ static const size_t kScavengeSpeed = 100 * KB;
+ static const size_t kNewSpaceCapacity = 1 * MB;
private:
GCIdleTimeHandler handler_;
@@ -99,6 +104,21 @@
size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
}
+
+
+TEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
+ size_t size = 1 * MB;
+ size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, 0);
+ EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeScavengeSpeed,
time);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateScavengeTimeNonZero) {
+ size_t size = 1 * MB;
+ size_t speed = 1 * MB;
+ size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, speed);
+ EXPECT_EQ(size / speed, time);
+}
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler.cc Tue Sep 16
12:48:59 2014 UTC
+++ /branches/bleeding_edge/src/heap/gc-idle-time-handler.cc Tue Sep 16
13:00:05 2014 UTC
@@ -71,9 +71,40 @@
}
+size_t GCIdleTimeHandler::EstimateScavengeTime(
+ size_t new_space_size, size_t scavenge_speed_in_bytes_per_ms) {
+ if (scavenge_speed_in_bytes_per_ms == 0) {
+ scavenge_speed_in_bytes_per_ms = kInitialConservativeScavengeSpeed;
+ }
+ return new_space_size / scavenge_speed_in_bytes_per_ms;
+}
+
+
+// The following logic is implemented by the controller:
+// (1) If the new space is almost full and we can effort a Scavenge, then a
+// Scavenge is performed.
+// (2) If there is currently no MarkCompact idle round going on, we start a
+// new idle round if enough garbage was created or we received a context
+// disposal event. Otherwise we do not perform garbage collection to keep
+// system utilization low.
+// (3) If incremental marking is done, we perform a full garbage collection
+// if context was disposed or if we are allowed to still do full garbage
+// collections during this idle round or if we are not allowed to start
+// incremental marking. Otherwise we do not perform garbage collection to
+// keep system utilization low.
+// (4) If sweeping is in progress and we received a large enough idle time
+// request, we finalize sweeping here.
+// (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(size_t idle_time_in_ms,
HeapState heap_state) {
- if (IsIdleRoundFinished()) {
+ if (heap_state.available_new_space_memory < kNewSpaceAlmostFullTreshold
&&
+ idle_time_in_ms >=
+ EstimateScavengeTime(heap_state.new_space_capacity,
+ heap_state.scavenge_speed_in_bytes_per_ms))
{
+ return GCIdleTimeAction::Scavenge();
+ }
+ if (IsMarkCompactIdleRoundFinished()) {
if (EnoughGarbageSinceLastIdleRound() || heap_state.contexts_disposed
0) {
StartIdleRound();
} else {
=======================================
--- /branches/bleeding_edge/src/heap/gc-idle-time-handler.h Tue Sep 16
12:48:59 2014 UTC
+++ /branches/bleeding_edge/src/heap/gc-idle-time-handler.h Tue Sep 16
13:00:05 2014 UTC
@@ -113,6 +113,14 @@
// That is the maximum idle time we will have during frame rendering.
static const size_t kMaxFrameRenderingIdleTime = 16;
+ // If less than that much memory is left in the new space, we consider it
+ // as almost full and force a new space collection earlier in the idle
time.
+ static const size_t kNewSpaceAlmostFullTreshold = 100 * KB;
+
+ // If we haven't recorded any scavenger events yet, we use a conservative
+ // lower bound for the scavenger speed.
+ static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
+
struct HeapState {
int contexts_disposed;
size_t size_of_objects;
@@ -121,6 +129,9 @@
bool sweeping_in_progress;
size_t mark_compact_speed_in_bytes_per_ms;
size_t incremental_marking_speed_in_bytes_per_ms;
+ size_t scavenge_speed_in_bytes_per_ms;
+ size_t available_new_space_memory;
+ size_t new_space_capacity;
};
GCIdleTimeHandler()
@@ -147,9 +158,12 @@
static size_t EstimateMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
+ static size_t EstimateScavengeTime(size_t new_space_size,
+ size_t
scavenger_speed_in_bytes_per_ms);
+
private:
void StartIdleRound() { mark_compacts_since_idle_round_started_ = 0; }
- bool IsIdleRoundFinished() {
+ bool IsMarkCompactIdleRoundFinished() {
return mark_compacts_since_idle_round_started_ ==
kMaxMarkCompactsInIdleRound;
}
=======================================
--- /branches/bleeding_edge/src/heap/heap.cc Tue Sep 16 12:48:59 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.cc Tue Sep 16 13:00:05 2014 UTC
@@ -4311,6 +4311,10 @@
static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
heap_state.incremental_marking_speed_in_bytes_per_ms =
static_cast<size_t>(
tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
+ heap_state.scavenge_speed_in_bytes_per_ms =
+ static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
+ heap_state.available_new_space_memory = new_space_.Available();
+ heap_state.new_space_capacity = new_space_.Capacity();
GCIdleTimeAction action =
gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
=======================================
--- /branches/bleeding_edge/src/heap/spaces.h Tue Sep 2 13:36:35 2014 UTC
+++ /branches/bleeding_edge/src/heap/spaces.h Tue Sep 16 13:00:05 2014 UTC
@@ -2013,7 +2013,7 @@
Address address() { return reinterpret_cast<Address>(this); }
- // Finds the NewSpacePage containg the given address.
+ // Finds the NewSpacePage containing the given address.
static inline NewSpacePage* FromAddress(Address address_in_page) {
Address page_start =
reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) &
--
--
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.