Commit 132af256 authored by alexeif@chromium.org's avatar alexeif@chromium.org

Split nodes and edges into separate arrays in heap profiler.

This allowed the following changes:
  - heap profiler now makes one pass less over the heap.
  - HeapEntriesMap does not allocate EntryInfo per each entry.
  - there's no need for an extra pass to set indexes before serialization.

As a result snapshot taking time has reduced up to 2x times.

Review URL: https://chromiumcodereview.appspot.com/10353010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11531 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b28f403c
......@@ -6063,7 +6063,7 @@ const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
return reinterpret_cast<const HeapGraphEdge*>(
&ToInternal(this)->children()[index]);
ToInternal(this)->children()[index]);
}
......@@ -6157,7 +6157,7 @@ const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
int HeapSnapshot::GetNodesCount() const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
return ToInternal(this)->entries()->length();
return ToInternal(this)->entries().length();
}
......@@ -6165,7 +6165,7 @@ const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
return reinterpret_cast<const HeapGraphNode*>(
ToInternal(this)->entries()->at(index));
&ToInternal(this)->entries().at(index));
}
......
......@@ -136,6 +136,14 @@ bool List<T, P>::RemoveElement(const T& elm) {
}
template<typename T, class P>
void List<T, P>::Allocate(int length) {
DeleteData(data_);
Initialize(length);
length_ = length;
}
template<typename T, class P>
void List<T, P>::Clear() {
DeleteData(data_);
......
......@@ -117,6 +117,9 @@ class List {
// pointer type. Returns the removed element.
INLINE(T RemoveLast()) { return Remove(length_ - 1); }
// Deletes current list contents and allocates space for 'length' elements.
INLINE(void Allocate(int length));
// Clears the list by setting the length to zero. Even if T is a
// pointer type, clearing the list doesn't delete the entries.
INLINE(void Clear());
......
......@@ -96,8 +96,51 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
HeapEntry* HeapGraphEdge::from() const {
return const_cast<HeapEntry*>(
reinterpret_cast<const HeapEntry*>(this - child_index_) - 1);
return &snapshot()->entries()[from_index_];
}
HeapSnapshot* HeapGraphEdge::snapshot() const {
return to_entry_->snapshot();
}
int HeapEntry::index() const {
return static_cast<int>(this - &snapshot_->entries().first());
}
int HeapEntry::set_children_index(int index) {
children_index_ = index;
int next_index = index + children_count_;
children_count_ = 0;
return next_index;
}
int HeapEntry::set_retainers_index(int index) {
retainers_index_ = index;
int next_index = index + retainers_count_;
retainers_count_ = 0;
return next_index;
}
HeapGraphEdge** HeapEntry::children_arr() {
ASSERT(children_index_ >= 0);
return &snapshot_->children()[children_index_];
}
HeapGraphEdge** HeapEntry::retainers_arr() {
ASSERT(retainers_index_ >= 0);
return &snapshot_->retainers()[retainers_index_];
}
HeapEntry* HeapEntry::dominator() const {
ASSERT(dominator_ >= 0);
return &snapshot_->entries()[dominator_];
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -34,10 +34,10 @@ class NamedEntriesDetector {
CheckEntry(root);
while (!list.is_empty()) {
i::HeapEntry* entry = list.RemoveLast();
i::Vector<i::HeapGraphEdge> children = entry->children();
i::Vector<i::HeapGraphEdge*> children = entry->children();
for (int i = 0; i < children.length(); ++i) {
if (children[i].type() == i::HeapGraphEdge::kShortcut) continue;
i::HeapEntry* child = children[i].to();
if (children[i]->type() == i::HeapGraphEdge::kShortcut) continue;
i::HeapEntry* child = children[i]->to();
if (!child->painted()) {
list.Add(child);
child->paint();
......
......@@ -130,6 +130,18 @@ TEST(RemoveLast) {
}
TEST(Allocate) {
List<int> list(4);
list.Add(1);
CHECK_EQ(1, list.length());
list.Allocate(100);
CHECK_EQ(100, list.length());
CHECK_LE(100, list.capacity());
list[99] = 123;
CHECK_EQ(123, list[99]);
}
TEST(Clear) {
List<int> list(4);
CHECK_EQ(0, list.length());
......
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