Commit ac4c14eb authored by ulan@chromium.org's avatar ulan@chromium.org

First tests for GCIdleTimeHandler.

BUG=
R=hpayer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23316 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1addf58e
...@@ -12,6 +12,8 @@ namespace internal { ...@@ -12,6 +12,8 @@ namespace internal {
const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9; const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000000; const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000000;
const size_t GCIdleTimeHandler::kMinTimeForFinalizeSweeping = 100; const size_t GCIdleTimeHandler::kMinTimeForFinalizeSweeping = 100;
const int GCIdleTimeHandler::kMaxMarkCompactsInIdleRound = 7;
const int GCIdleTimeHandler::kIdleScavengeThreshold = 5;
size_t GCIdleTimeHandler::EstimateMarkingStepSize( size_t GCIdleTimeHandler::EstimateMarkingStepSize(
......
...@@ -89,6 +89,13 @@ class GCIdleTimeHandler { ...@@ -89,6 +89,13 @@ class GCIdleTimeHandler {
// sweeper threads. // sweeper threads.
static const size_t kMinTimeForFinalizeSweeping; static const size_t kMinTimeForFinalizeSweeping;
// Number of idle mark-compact events, after which idle handler will finish
// idle round.
static const int kMaxMarkCompactsInIdleRound;
// Number of scavenges that will trigger start of new idle round.
static const int kIdleScavengeThreshold;
struct HeapState { struct HeapState {
int contexts_disposed; int contexts_disposed;
size_t size_of_objects; size_t size_of_objects;
...@@ -133,8 +140,6 @@ class GCIdleTimeHandler { ...@@ -133,8 +140,6 @@ class GCIdleTimeHandler {
return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold; return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
} }
static const int kMaxMarkCompactsInIdleRound = 7;
static const int kIdleScavengeThreshold = 5;
int mark_compacts_since_idle_round_started_; int mark_compacts_since_idle_round_started_;
int scavenges_since_last_idle_round_; int scavenges_since_last_idle_round_;
......
...@@ -2,11 +2,10 @@ ...@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <limits> #include "test/heap-unittests/heap-unittest.h"
#include "src/heap/gc-idle-time-handler.h" #include <limits>
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -69,5 +68,143 @@ TEST(EstimateMarkCompactTimeTest, EstimateMarkCompactTimeMax) { ...@@ -69,5 +68,143 @@ TEST(EstimateMarkCompactTimeTest, EstimateMarkCompactTimeMax) {
EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time); EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
} }
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = (heap_state.size_of_objects + speed - 1) / speed;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type);
}
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = heap_state.size_of_objects / speed - 1;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = heap_state.size_of_objects / speed - 1;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
int idle_time_ms = 10;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
EXPECT_GT(speed * idle_time_ms, action.parameter);
EXPECT_LT(0, action.parameter);
}
TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
int idle_time_ms = 10;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
EXPECT_GT(speed * idle_time_ms, action.parameter);
EXPECT_LT(0, action.parameter);
}
TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = heap_state.size_of_objects / speed - 1;
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = heap_state.size_of_objects / speed + 1;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type);
handler()->NotifyIdleMarkCompact();
}
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
handler()->NotifyIdleMarkCompact();
}
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
}
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.incremental_marking_stopped = true;
heap_state.can_start_incremental_marking = false;
size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
int idle_time_ms = heap_state.size_of_objects / speed + 1;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type);
handler()->NotifyIdleMarkCompact();
}
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
// Emulate mutator work.
for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
handler()->NotifyScavenge();
}
action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_FULL_GC, action.type);
}
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
int idle_time_ms = 10;
for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
if (action.type == DO_NOTHING) break;
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
handler()->NotifyIdleMarkCompact();
}
GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_NOTHING, action.type);
// Emulate mutator work.
for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
handler()->NotifyScavenge();
}
action = handler()->Compute(idle_time_ms, heap_state);
EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_UNITTESTS_HEAP_UNITTEST_H_
#define V8_HEAP_UNITTESTS_HEAP_UNITTEST_H_
#include "src/heap/gc-idle-time-handler.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
class GCIdleTimeHandlerTest : public ::testing::Test {
public:
GCIdleTimeHandlerTest() {}
virtual ~GCIdleTimeHandlerTest() {}
GCIdleTimeHandler* handler() { return &handler_; }
GCIdleTimeHandler::HeapState DefaultHeapState() {
GCIdleTimeHandler::HeapState result;
result.contexts_disposed = 0;
result.size_of_objects = kSizeOfObjects;
result.incremental_marking_stopped = false;
result.can_start_incremental_marking = true;
result.sweeping_in_progress = false;
result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
return result;
}
static const size_t kSizeOfObjects = 100 * MB;
static const size_t kMarkCompactSpeed = 100 * KB;
static const size_t kMarkingSpeed = 100 * KB;
private:
GCIdleTimeHandler handler_;
};
}
}
#endif // V8_HEAP_UNITTESTS_HEAP_UNITTEST_H_
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