Permalink
Browse files

New heap profiler: add support for progress reporting and control.

As taking a snapshot of a large heap takes noticeable time, it's
good to be able to monitor and control it.

The change itself is small, big code deletes and additions are in
fact moves. The only significant change is simplification of
approximated retained sizes calculation algorithm.

Review URL: http://codereview.chromium.org/5687003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5978 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information...
1 parent b1a2cc1 commit 5cf643aa422251553a68759ace499fd8b4f2cf8d mikhail.naganov@gmail.com committed Dec 13, 2010
Showing with 348 additions and 206 deletions.
  1. +2 −2 include/v8-profiler.h
  2. +18 −0 include/v8.h
  3. +4 −2 src/api.cc
  4. +23 −10 src/heap-profiler.cc
  5. +12 −4 src/heap-profiler.h
  6. +13 −1 src/profile-generator-inl.h
  7. +207 −166 src/profile-generator.cc
  8. +21 −20 src/profile-generator.h
  9. +1 −1 src/runtime.cc
  10. +47 −0 test/cctest/test-heap-profiler.cc
@@ -245,7 +245,6 @@ class V8EXPORT HeapGraphPath {
class V8EXPORT HeapGraphNode {
public:
enum Type {
- kInternal = 0, // For compatibility, will be removed.
kHidden = 0, // Hidden node, may be filtered when shown to user.
kArray = 1, // An array of elements.
kString = 2, // A string.
@@ -413,7 +412,8 @@ class V8EXPORT HeapProfiler {
*/
static const HeapSnapshot* TakeSnapshot(
Handle<String> title,
- HeapSnapshot::Type type = HeapSnapshot::kFull);
+ HeapSnapshot::Type type = HeapSnapshot::kFull,
+ ActivityControl* control = NULL);
};
View
@@ -3281,6 +3281,24 @@ class V8EXPORT OutputStream { // NOLINT
};
+/**
+ * An interface for reporting progress and controlling long-running
+ * activities.
+ */
+class V8EXPORT ActivityControl { // NOLINT
+ public:
+ enum ControlOption {
+ kContinue = 0,
+ kAbort = 1
+ };
+ virtual ~ActivityControl() {}
+ /**
+ * Notify about current progress. The activity can be stopped by
+ * returning kAbort as the callback result.
+ */
+ virtual ControlOption ReportProgressValue(int done, int total) = 0;
+};
+
// --- I m p l e m e n t a t i o n ---
View
@@ -4947,7 +4947,8 @@ const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
- HeapSnapshot::Type type) {
+ HeapSnapshot::Type type,
+ ActivityControl* control) {
IsDeadCheck("v8::HeapProfiler::TakeSnapshot");
i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
switch (type) {
@@ -4961,7 +4962,8 @@ const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
UNREACHABLE();
}
return reinterpret_cast<const HeapSnapshot*>(
- i::HeapProfiler::TakeSnapshot(*Utils::OpenHandle(*title), internal_type));
+ i::HeapProfiler::TakeSnapshot(
+ *Utils::OpenHandle(*title), internal_type, control));
}
#endif // ENABLE_LOGGING_AND_PROFILING
View
@@ -348,27 +348,34 @@ void HeapProfiler::TearDown() {
#ifdef ENABLE_LOGGING_AND_PROFILING
-HeapSnapshot* HeapProfiler::TakeSnapshot(const char* name, int type) {
+HeapSnapshot* HeapProfiler::TakeSnapshot(const char* name,
+ int type,
+ v8::ActivityControl* control) {
ASSERT(singleton_ != NULL);
- return singleton_->TakeSnapshotImpl(name, type);
+ return singleton_->TakeSnapshotImpl(name, type, control);
}
-HeapSnapshot* HeapProfiler::TakeSnapshot(String* name, int type) {
+HeapSnapshot* HeapProfiler::TakeSnapshot(String* name,
+ int type,
+ v8::ActivityControl* control) {
ASSERT(singleton_ != NULL);
- return singleton_->TakeSnapshotImpl(name, type);
+ return singleton_->TakeSnapshotImpl(name, type, control);
}
-HeapSnapshot* HeapProfiler::TakeSnapshotImpl(const char* name, int type) {
+HeapSnapshot* HeapProfiler::TakeSnapshotImpl(const char* name,
+ int type,
+ v8::ActivityControl* control) {
Heap::CollectAllGarbage(true);
HeapSnapshot::Type s_type = static_cast<HeapSnapshot::Type>(type);
HeapSnapshot* result =
snapshots_->NewSnapshot(s_type, name, next_snapshot_uid_++);
+ bool generation_completed = true;
switch (s_type) {
case HeapSnapshot::kFull: {
- HeapSnapshotGenerator generator(result);
- generator.GenerateSnapshot();
+ HeapSnapshotGenerator generator(result, control);
+ generation_completed = generator.GenerateSnapshot();
break;
}
case HeapSnapshot::kAggregated: {
@@ -381,13 +388,19 @@ HeapSnapshot* HeapProfiler::TakeSnapshotImpl(const char* name, int type) {
default:
UNREACHABLE();
}
- snapshots_->SnapshotGenerationFinished();
+ if (!generation_completed) {
+ delete result;
+ result = NULL;
+ }
+ snapshots_->SnapshotGenerationFinished(result);
return result;
}
-HeapSnapshot* HeapProfiler::TakeSnapshotImpl(String* name, int type) {
- return TakeSnapshotImpl(snapshots_->GetName(name), type);
+HeapSnapshot* HeapProfiler::TakeSnapshotImpl(String* name,
+ int type,
+ v8::ActivityControl* control) {
+ return TakeSnapshotImpl(snapshots_->GetName(name), type, control);
}
View
@@ -56,8 +56,12 @@ class HeapProfiler {
static void TearDown();
#ifdef ENABLE_LOGGING_AND_PROFILING
- static HeapSnapshot* TakeSnapshot(const char* name, int type);
- static HeapSnapshot* TakeSnapshot(String* name, int type);
+ static HeapSnapshot* TakeSnapshot(const char* name,
+ int type,
+ v8::ActivityControl* control);
+ static HeapSnapshot* TakeSnapshot(String* name,
+ int type,
+ v8::ActivityControl* control);
static int GetSnapshotsCount();
static HeapSnapshot* GetSnapshot(int index);
static HeapSnapshot* FindSnapshot(unsigned uid);
@@ -75,8 +79,12 @@ class HeapProfiler {
private:
HeapProfiler();
~HeapProfiler();
- HeapSnapshot* TakeSnapshotImpl(const char* name, int type);
- HeapSnapshot* TakeSnapshotImpl(String* name, int type);
+ HeapSnapshot* TakeSnapshotImpl(const char* name,
+ int type,
+ v8::ActivityControl* control);
+ HeapSnapshot* TakeSnapshotImpl(String* name,
+ int type,
+ v8::ActivityControl* control);
HeapSnapshotsCollection* snapshots_;
unsigned next_snapshot_uid_;
@@ -122,7 +122,7 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
}
-inline uint64_t HeapEntry::id() {
+uint64_t HeapEntry::id() {
union {
Id stored_id;
uint64_t returned_id;
@@ -146,6 +146,18 @@ void HeapEntriesMap::UpdateEntries(Visitor* visitor) {
}
}
+
+bool HeapSnapshotGenerator::ReportProgress(bool force) {
+ const int kProgressReportGranularity = 10000;
+ if (control_ != NULL
+ && (force || progress_counter_ % kProgressReportGranularity == 0)) {
+ return
+ control_->ReportProgressValue(progress_counter_, progress_total_) ==
+ v8::ActivityControl::kContinue;
+ }
+ return true;
+}
+
} } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING
Oops, something went wrong.

0 comments on commit 5cf643a

Please sign in to comment.