Refactor heap profiler's code to make possible including
into heap snapshots non-HeapObjects. This is needed as a preparation for adding DOM subtrees tracking. BUG=none TEST=none Review URL: http://codereview.chromium.org/6596073 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7004 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
63beeed358
commit
60711c074f
@ -911,22 +911,27 @@ static JSObjectsCluster HeapObjectAsCluster(HeapObject* object) {
|
|||||||
class CountingRetainersIterator {
|
class CountingRetainersIterator {
|
||||||
public:
|
public:
|
||||||
CountingRetainersIterator(const JSObjectsCluster& child_cluster,
|
CountingRetainersIterator(const JSObjectsCluster& child_cluster,
|
||||||
|
HeapEntriesAllocator* allocator,
|
||||||
HeapEntriesMap* map)
|
HeapEntriesMap* map)
|
||||||
: child_(ClusterAsHeapObject(child_cluster)), map_(map) {
|
: child_(ClusterAsHeapObject(child_cluster)),
|
||||||
|
allocator_(allocator),
|
||||||
|
map_(map) {
|
||||||
if (map_->Map(child_) == NULL)
|
if (map_->Map(child_) == NULL)
|
||||||
map_->Pair(child_, HeapEntriesMap::kHeapEntryPlaceholder);
|
map_->Pair(child_, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call(const JSObjectsCluster& cluster,
|
void Call(const JSObjectsCluster& cluster,
|
||||||
const NumberAndSizeInfo& number_and_size) {
|
const NumberAndSizeInfo& number_and_size) {
|
||||||
if (map_->Map(ClusterAsHeapObject(cluster)) == NULL)
|
if (map_->Map(ClusterAsHeapObject(cluster)) == NULL)
|
||||||
map_->Pair(ClusterAsHeapObject(cluster),
|
map_->Pair(ClusterAsHeapObject(cluster),
|
||||||
|
allocator_,
|
||||||
HeapEntriesMap::kHeapEntryPlaceholder);
|
HeapEntriesMap::kHeapEntryPlaceholder);
|
||||||
map_->CountReference(ClusterAsHeapObject(cluster), child_);
|
map_->CountReference(ClusterAsHeapObject(cluster), child_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HeapObject* child_;
|
HeapObject* child_;
|
||||||
|
HeapEntriesAllocator* allocator_;
|
||||||
HeapEntriesMap* map_;
|
HeapEntriesMap* map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -934,6 +939,7 @@ class CountingRetainersIterator {
|
|||||||
class AllocatingRetainersIterator {
|
class AllocatingRetainersIterator {
|
||||||
public:
|
public:
|
||||||
AllocatingRetainersIterator(const JSObjectsCluster& child_cluster,
|
AllocatingRetainersIterator(const JSObjectsCluster& child_cluster,
|
||||||
|
HeapEntriesAllocator*,
|
||||||
HeapEntriesMap* map)
|
HeapEntriesMap* map)
|
||||||
: child_(ClusterAsHeapObject(child_cluster)), map_(map) {
|
: child_(ClusterAsHeapObject(child_cluster)), map_(map) {
|
||||||
child_entry_ = map_->Map(child_);
|
child_entry_ = map_->Map(child_);
|
||||||
@ -966,8 +972,9 @@ template<class RetainersIterator>
|
|||||||
class AggregatingRetainerTreeIterator {
|
class AggregatingRetainerTreeIterator {
|
||||||
public:
|
public:
|
||||||
explicit AggregatingRetainerTreeIterator(ClustersCoarser* coarser,
|
explicit AggregatingRetainerTreeIterator(ClustersCoarser* coarser,
|
||||||
|
HeapEntriesAllocator* allocator,
|
||||||
HeapEntriesMap* map)
|
HeapEntriesMap* map)
|
||||||
: coarser_(coarser), map_(map) {
|
: coarser_(coarser), allocator_(allocator), map_(map) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree) {
|
void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree) {
|
||||||
@ -981,25 +988,28 @@ class AggregatingRetainerTreeIterator {
|
|||||||
tree->ForEach(&retainers_aggregator);
|
tree->ForEach(&retainers_aggregator);
|
||||||
tree_to_iterate = &dest_tree_;
|
tree_to_iterate = &dest_tree_;
|
||||||
}
|
}
|
||||||
RetainersIterator iterator(cluster, map_);
|
RetainersIterator iterator(cluster, allocator_, map_);
|
||||||
tree_to_iterate->ForEach(&iterator);
|
tree_to_iterate->ForEach(&iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClustersCoarser* coarser_;
|
ClustersCoarser* coarser_;
|
||||||
|
HeapEntriesAllocator* allocator_;
|
||||||
HeapEntriesMap* map_;
|
HeapEntriesMap* map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class AggregatedRetainerTreeAllocator {
|
class AggregatedRetainerTreeAllocator : public HeapEntriesAllocator {
|
||||||
public:
|
public:
|
||||||
AggregatedRetainerTreeAllocator(HeapSnapshot* snapshot,
|
AggregatedRetainerTreeAllocator(HeapSnapshot* snapshot,
|
||||||
int* root_child_index)
|
int* root_child_index)
|
||||||
: snapshot_(snapshot), root_child_index_(root_child_index) {
|
: snapshot_(snapshot), root_child_index_(root_child_index) {
|
||||||
}
|
}
|
||||||
|
~AggregatedRetainerTreeAllocator() { }
|
||||||
|
|
||||||
HeapEntry* GetEntry(
|
HeapEntry* AllocateEntry(
|
||||||
HeapObject* obj, int children_count, int retainers_count) {
|
HeapThing ptr, int children_count, int retainers_count) {
|
||||||
|
HeapObject* obj = reinterpret_cast<HeapObject*>(ptr);
|
||||||
JSObjectsCluster cluster = HeapObjectAsCluster(obj);
|
JSObjectsCluster cluster = HeapObjectAsCluster(obj);
|
||||||
const char* name = cluster.GetSpecialCaseName();
|
const char* name = cluster.GetSpecialCaseName();
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
@ -1018,12 +1028,13 @@ class AggregatedRetainerTreeAllocator {
|
|||||||
|
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
void AggregatedHeapSnapshotGenerator::IterateRetainers(
|
void AggregatedHeapSnapshotGenerator::IterateRetainers(
|
||||||
HeapEntriesMap* entries_map) {
|
HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map) {
|
||||||
RetainerHeapProfile* p = agg_snapshot_->js_retainer_profile();
|
RetainerHeapProfile* p = agg_snapshot_->js_retainer_profile();
|
||||||
AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_1(
|
AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_1(
|
||||||
p->coarser(), entries_map);
|
p->coarser(), allocator, entries_map);
|
||||||
p->retainers_tree()->ForEach(&agg_ret_iter_1);
|
p->retainers_tree()->ForEach(&agg_ret_iter_1);
|
||||||
AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_2(NULL, entries_map);
|
AggregatingRetainerTreeIterator<Iterator> agg_ret_iter_2(
|
||||||
|
NULL, allocator, entries_map);
|
||||||
p->aggregator()->output_tree().ForEach(&agg_ret_iter_2);
|
p->aggregator()->output_tree().ForEach(&agg_ret_iter_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +1053,9 @@ void AggregatedHeapSnapshotGenerator::FillHeapSnapshot(HeapSnapshot* snapshot) {
|
|||||||
agg_snapshot_->js_cons_profile()->ForEach(&counting_cons_iter);
|
agg_snapshot_->js_cons_profile()->ForEach(&counting_cons_iter);
|
||||||
histogram_entities_count += counting_cons_iter.entities_count();
|
histogram_entities_count += counting_cons_iter.entities_count();
|
||||||
HeapEntriesMap entries_map;
|
HeapEntriesMap entries_map;
|
||||||
IterateRetainers<CountingRetainersIterator>(&entries_map);
|
int root_child_index = 0;
|
||||||
|
AggregatedRetainerTreeAllocator allocator(snapshot, &root_child_index);
|
||||||
|
IterateRetainers<CountingRetainersIterator>(&allocator, &entries_map);
|
||||||
histogram_entities_count += entries_map.entries_count();
|
histogram_entities_count += entries_map.entries_count();
|
||||||
histogram_children_count += entries_map.total_children_count();
|
histogram_children_count += entries_map.total_children_count();
|
||||||
histogram_retainers_count += entries_map.total_retainers_count();
|
histogram_retainers_count += entries_map.total_retainers_count();
|
||||||
@ -1056,10 +1069,7 @@ void AggregatedHeapSnapshotGenerator::FillHeapSnapshot(HeapSnapshot* snapshot) {
|
|||||||
snapshot->AllocateEntries(histogram_entities_count,
|
snapshot->AllocateEntries(histogram_entities_count,
|
||||||
histogram_children_count,
|
histogram_children_count,
|
||||||
histogram_retainers_count);
|
histogram_retainers_count);
|
||||||
snapshot->AddEntry(HeapSnapshot::kInternalRootObject,
|
snapshot->AddRootEntry(root_children_count);
|
||||||
root_children_count,
|
|
||||||
0);
|
|
||||||
int root_child_index = 0;
|
|
||||||
for (int i = FIRST_NONSTRING_TYPE; i <= kAllStringsType; ++i) {
|
for (int i = FIRST_NONSTRING_TYPE; i <= kAllStringsType; ++i) {
|
||||||
if (agg_snapshot_->info()[i].bytes() > 0) {
|
if (agg_snapshot_->info()[i].bytes() > 0) {
|
||||||
AddEntryFromAggregatedSnapshot(snapshot,
|
AddEntryFromAggregatedSnapshot(snapshot,
|
||||||
@ -1075,11 +1085,10 @@ void AggregatedHeapSnapshotGenerator::FillHeapSnapshot(HeapSnapshot* snapshot) {
|
|||||||
AllocatingConstructorHeapProfileIterator alloc_cons_iter(
|
AllocatingConstructorHeapProfileIterator alloc_cons_iter(
|
||||||
snapshot, &root_child_index);
|
snapshot, &root_child_index);
|
||||||
agg_snapshot_->js_cons_profile()->ForEach(&alloc_cons_iter);
|
agg_snapshot_->js_cons_profile()->ForEach(&alloc_cons_iter);
|
||||||
AggregatedRetainerTreeAllocator allocator(snapshot, &root_child_index);
|
entries_map.AllocateEntries();
|
||||||
entries_map.UpdateEntries(&allocator);
|
|
||||||
|
|
||||||
// Fill up references.
|
// Fill up references.
|
||||||
IterateRetainers<AllocatingRetainersIterator>(&entries_map);
|
IterateRetainers<AllocatingRetainersIterator>(&allocator, &entries_map);
|
||||||
|
|
||||||
snapshot->SetDominatorsToSelf();
|
snapshot->SetDominatorsToSelf();
|
||||||
}
|
}
|
||||||
|
@ -340,6 +340,7 @@ class AggregatedHeapSnapshot {
|
|||||||
|
|
||||||
|
|
||||||
class HeapEntriesMap;
|
class HeapEntriesMap;
|
||||||
|
class HeapEntriesAllocator;
|
||||||
class HeapSnapshot;
|
class HeapSnapshot;
|
||||||
|
|
||||||
class AggregatedHeapSnapshotGenerator {
|
class AggregatedHeapSnapshotGenerator {
|
||||||
@ -354,7 +355,8 @@ class AggregatedHeapSnapshotGenerator {
|
|||||||
void CalculateStringsStats();
|
void CalculateStringsStats();
|
||||||
void CollectStats(HeapObject* obj);
|
void CollectStats(HeapObject* obj);
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
void IterateRetainers(HeapEntriesMap* entries_map);
|
void IterateRetainers(
|
||||||
|
HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map);
|
||||||
|
|
||||||
AggregatedHeapSnapshot* agg_snapshot_;
|
AggregatedHeapSnapshot* agg_snapshot_;
|
||||||
};
|
};
|
||||||
|
@ -121,34 +121,6 @@ uint64_t HeapEntry::id() {
|
|||||||
return id_adaptor.returned_id;
|
return id_adaptor.returned_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Visitor>
|
|
||||||
void HeapEntriesMap::UpdateEntries(Visitor* visitor) {
|
|
||||||
for (HashMap::Entry* p = entries_.Start();
|
|
||||||
p != NULL;
|
|
||||||
p = entries_.Next(p)) {
|
|
||||||
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
|
|
||||||
entry_info->entry = visitor->GetEntry(
|
|
||||||
reinterpret_cast<HeapObject*>(p->key),
|
|
||||||
entry_info->children_count,
|
|
||||||
entry_info->retainers_count);
|
|
||||||
entry_info->children_count = 0;
|
|
||||||
entry_info->retainers_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
} } // namespace v8::internal
|
||||||
|
|
||||||
#endif // ENABLE_LOGGING_AND_PROFILING
|
#endif // ENABLE_LOGGING_AND_PROFILING
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -681,14 +681,14 @@ class HeapSnapshot {
|
|||||||
|
|
||||||
void AllocateEntries(
|
void AllocateEntries(
|
||||||
int entries_count, int children_count, int retainers_count);
|
int entries_count, int children_count, int retainers_count);
|
||||||
HeapEntry* AddEntry(
|
|
||||||
HeapObject* object, int children_count, int retainers_count);
|
|
||||||
HeapEntry* AddEntry(HeapEntry::Type type,
|
HeapEntry* AddEntry(HeapEntry::Type type,
|
||||||
const char* name,
|
const char* name,
|
||||||
uint64_t id,
|
uint64_t id,
|
||||||
int size,
|
int size,
|
||||||
int children_count,
|
int children_count,
|
||||||
int retainers_count);
|
int retainers_count);
|
||||||
|
HeapEntry* AddRootEntry(int children_count);
|
||||||
|
HeapEntry* AddGcRootsEntry(int children_count, int retainers_count);
|
||||||
void ClearPaint();
|
void ClearPaint();
|
||||||
HeapSnapshotsDiff* CompareWith(HeapSnapshot* snapshot);
|
HeapSnapshotsDiff* CompareWith(HeapSnapshot* snapshot);
|
||||||
HeapEntry* GetEntryById(uint64_t id);
|
HeapEntry* GetEntryById(uint64_t id);
|
||||||
@ -701,15 +701,7 @@ class HeapSnapshot {
|
|||||||
void Print(int max_depth);
|
void Print(int max_depth);
|
||||||
void PrintEntriesSize();
|
void PrintEntriesSize();
|
||||||
|
|
||||||
static HeapObject* const kInternalRootObject;
|
|
||||||
static HeapObject* const kGcRootsObject;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HeapEntry* AddEntry(HeapObject* object,
|
|
||||||
HeapEntry::Type type,
|
|
||||||
const char* name,
|
|
||||||
int children_count,
|
|
||||||
int retainers_count);
|
|
||||||
HeapEntry* GetNextEntryToInit();
|
HeapEntry* GetNextEntryToInit();
|
||||||
|
|
||||||
HeapSnapshotsCollection* collection_;
|
HeapSnapshotsCollection* collection_;
|
||||||
@ -873,6 +865,20 @@ class HeapSnapshotsCollection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// A typedef for referencing anything that can be snapshotted living
|
||||||
|
// in any kind of heap memory.
|
||||||
|
typedef void* HeapThing;
|
||||||
|
|
||||||
|
|
||||||
|
// An interface that creates HeapEntries by HeapThings.
|
||||||
|
class HeapEntriesAllocator {
|
||||||
|
public:
|
||||||
|
virtual ~HeapEntriesAllocator() { }
|
||||||
|
virtual HeapEntry* AllocateEntry(
|
||||||
|
HeapThing ptr, int children_count, int retainers_count) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// The HeapEntriesMap instance is used to track a mapping between
|
// The HeapEntriesMap instance is used to track a mapping between
|
||||||
// real heap objects and their representations in heap snapshots.
|
// real heap objects and their representations in heap snapshots.
|
||||||
class HeapEntriesMap {
|
class HeapEntriesMap {
|
||||||
@ -880,13 +886,12 @@ class HeapEntriesMap {
|
|||||||
HeapEntriesMap();
|
HeapEntriesMap();
|
||||||
~HeapEntriesMap();
|
~HeapEntriesMap();
|
||||||
|
|
||||||
HeapEntry* Map(HeapObject* object);
|
void AllocateEntries();
|
||||||
void Pair(HeapObject* object, HeapEntry* entry);
|
HeapEntry* Map(HeapThing thing);
|
||||||
void CountReference(HeapObject* from, HeapObject* to,
|
void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry);
|
||||||
|
void CountReference(HeapThing from, HeapThing to,
|
||||||
int* prev_children_count = NULL,
|
int* prev_children_count = NULL,
|
||||||
int* prev_retainers_count = NULL);
|
int* prev_retainers_count = NULL);
|
||||||
template<class Visitor>
|
|
||||||
void UpdateEntries(Visitor* visitor);
|
|
||||||
|
|
||||||
int entries_count() { return entries_count_; }
|
int entries_count() { return entries_count_; }
|
||||||
int total_children_count() { return total_children_count_; }
|
int total_children_count() { return total_children_count_; }
|
||||||
@ -896,18 +901,25 @@ class HeapEntriesMap {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct EntryInfo {
|
struct EntryInfo {
|
||||||
explicit EntryInfo(HeapEntry* entry)
|
EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator)
|
||||||
: entry(entry), children_count(0), retainers_count(0) { }
|
: entry(entry),
|
||||||
|
allocator(allocator),
|
||||||
|
children_count(0),
|
||||||
|
retainers_count(0) {
|
||||||
|
}
|
||||||
HeapEntry* entry;
|
HeapEntry* entry;
|
||||||
|
HeapEntriesAllocator* allocator;
|
||||||
int children_count;
|
int children_count;
|
||||||
int retainers_count;
|
int retainers_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t Hash(HeapObject* object) {
|
static uint32_t Hash(HeapThing thing) {
|
||||||
return ComputeIntegerHash(
|
return ComputeIntegerHash(
|
||||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object)));
|
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)));
|
||||||
|
}
|
||||||
|
static bool HeapThingsMatch(HeapThing key1, HeapThing key2) {
|
||||||
|
return key1 == key2;
|
||||||
}
|
}
|
||||||
static bool HeapObjectsMatch(void* key1, void* key2) { return key1 == key2; }
|
|
||||||
|
|
||||||
HashMap entries_;
|
HashMap entries_;
|
||||||
int entries_count_;
|
int entries_count_;
|
||||||
@ -934,52 +946,70 @@ class HeapObjectsSet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class HeapSnapshotGenerator {
|
// An interface used to populate a snapshot with nodes and edges.
|
||||||
|
class SnapshotFillerInterface {
|
||||||
public:
|
public:
|
||||||
class SnapshotFillerInterface {
|
virtual ~SnapshotFillerInterface() { }
|
||||||
public:
|
virtual HeapEntry* AddEntry(HeapThing ptr) = 0;
|
||||||
virtual ~SnapshotFillerInterface() { }
|
virtual HeapEntry* FindOrAddEntry(HeapThing ptr) = 0;
|
||||||
virtual HeapEntry* AddEntry(HeapObject* obj) = 0;
|
virtual void SetIndexedReference(HeapGraphEdge::Type type,
|
||||||
virtual void SetIndexedReference(HeapGraphEdge::Type type,
|
HeapThing parent_ptr,
|
||||||
HeapObject* parent_obj,
|
|
||||||
HeapEntry* parent_entry,
|
|
||||||
int index,
|
|
||||||
Object* child_obj,
|
|
||||||
HeapEntry* child_entry) = 0;
|
|
||||||
virtual void SetNamedReference(HeapGraphEdge::Type type,
|
|
||||||
HeapObject* parent_obj,
|
|
||||||
HeapEntry* parent_entry,
|
HeapEntry* parent_entry,
|
||||||
const char* reference_name,
|
int index,
|
||||||
Object* child_obj,
|
HeapThing child_ptr,
|
||||||
HeapEntry* child_entry) = 0;
|
HeapEntry* child_entry) = 0;
|
||||||
virtual void SetRootGcRootsReference() = 0;
|
virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
|
||||||
virtual void SetRootShortcutReference(Object* child_obj,
|
HeapThing parent_ptr,
|
||||||
|
HeapEntry* parent_entry,
|
||||||
|
HeapThing child_ptr,
|
||||||
|
HeapEntry* child_entry) = 0;
|
||||||
|
virtual void SetNamedReference(HeapGraphEdge::Type type,
|
||||||
|
HeapThing parent_ptr,
|
||||||
|
HeapEntry* parent_entry,
|
||||||
|
const char* reference_name,
|
||||||
|
HeapThing child_ptr,
|
||||||
|
HeapEntry* child_entry) = 0;
|
||||||
|
virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
|
||||||
|
HeapThing parent_ptr,
|
||||||
|
HeapEntry* parent_entry,
|
||||||
|
HeapThing child_ptr,
|
||||||
HeapEntry* child_entry) = 0;
|
HeapEntry* child_entry) = 0;
|
||||||
virtual void SetStrongRootReference(Object* child_obj,
|
};
|
||||||
HeapEntry* child_entry) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
HeapSnapshotGenerator(HeapSnapshot* snapshot,
|
|
||||||
v8::ActivityControl* control);
|
class SnapshottingProgressReportingInterface {
|
||||||
bool GenerateSnapshot();
|
public:
|
||||||
|
virtual ~SnapshottingProgressReportingInterface() { }
|
||||||
|
virtual void ProgressStep() = 0;
|
||||||
|
virtual bool ProgressReport(bool force) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// An implementation of V8 heap graph extractor.
|
||||||
|
class V8HeapExplorer : public HeapEntriesAllocator {
|
||||||
|
public:
|
||||||
|
V8HeapExplorer(HeapSnapshot* snapshot,
|
||||||
|
SnapshottingProgressReportingInterface* progress);
|
||||||
|
~V8HeapExplorer();
|
||||||
|
virtual HeapEntry* AllocateEntry(
|
||||||
|
HeapThing ptr, int children_count, int retainers_count);
|
||||||
|
void AddRootEntries(SnapshotFillerInterface* filler);
|
||||||
|
int EstimateObjectsCount();
|
||||||
|
bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ApproximateRetainedSizes();
|
HeapEntry* AddEntry(
|
||||||
bool BuildDominatorTree(const Vector<HeapEntry*>& entries,
|
HeapObject* object, int children_count, int retainers_count);
|
||||||
Vector<HeapEntry*>* dominators);
|
HeapEntry* AddEntry(HeapObject* object,
|
||||||
bool CountEntriesAndReferences();
|
HeapEntry::Type type,
|
||||||
HeapEntry* GetEntry(Object* obj);
|
const char* name,
|
||||||
void IncProgressCounter() { ++progress_counter_; }
|
int children_count,
|
||||||
|
int retainers_count);
|
||||||
void ExtractReferences(HeapObject* obj);
|
void ExtractReferences(HeapObject* obj);
|
||||||
void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
|
void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
|
||||||
void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
|
void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
|
||||||
void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);
|
void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);
|
||||||
void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry);
|
void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry);
|
||||||
bool FillReferences();
|
|
||||||
void FillReversePostorderIndexes(Vector<HeapEntry*>* entries);
|
|
||||||
bool IterateAndExtractReferences();
|
|
||||||
inline bool ReportProgress(bool force = false);
|
|
||||||
bool SetEntriesDominators();
|
|
||||||
void SetClosureReference(HeapObject* parent_obj,
|
void SetClosureReference(HeapObject* parent_obj,
|
||||||
HeapEntry* parent,
|
HeapEntry* parent,
|
||||||
String* reference_name,
|
String* reference_name,
|
||||||
@ -1011,24 +1041,54 @@ class HeapSnapshotGenerator {
|
|||||||
void SetRootShortcutReference(Object* child);
|
void SetRootShortcutReference(Object* child);
|
||||||
void SetRootGcRootsReference();
|
void SetRootGcRootsReference();
|
||||||
void SetGcRootsReference(Object* child);
|
void SetGcRootsReference(Object* child);
|
||||||
|
|
||||||
|
HeapEntry* GetEntry(Object* obj);
|
||||||
|
|
||||||
|
HeapSnapshot* snapshot_;
|
||||||
|
HeapSnapshotsCollection* collection_;
|
||||||
|
SnapshottingProgressReportingInterface* progress_;
|
||||||
|
// Used during references extraction to mark heap objects that
|
||||||
|
// are references via non-hidden properties.
|
||||||
|
HeapObjectsSet known_references_;
|
||||||
|
SnapshotFillerInterface* filler_;
|
||||||
|
|
||||||
|
static HeapObject* const kInternalRootObject;
|
||||||
|
static HeapObject* const kGcRootsObject;
|
||||||
|
|
||||||
|
friend class IndexedReferencesExtractor;
|
||||||
|
friend class RootsReferencesExtractor;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
|
||||||
|
public:
|
||||||
|
HeapSnapshotGenerator(HeapSnapshot* snapshot,
|
||||||
|
v8::ActivityControl* control);
|
||||||
|
bool GenerateSnapshot();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ApproximateRetainedSizes();
|
||||||
|
bool BuildDominatorTree(const Vector<HeapEntry*>& entries,
|
||||||
|
Vector<HeapEntry*>* dominators);
|
||||||
|
bool CountEntriesAndReferences();
|
||||||
|
bool FillReferences();
|
||||||
|
void FillReversePostorderIndexes(Vector<HeapEntry*>* entries);
|
||||||
|
void ProgressStep();
|
||||||
|
bool ProgressReport(bool force = false);
|
||||||
|
bool SetEntriesDominators();
|
||||||
void SetProgressTotal(int iterations_count);
|
void SetProgressTotal(int iterations_count);
|
||||||
|
|
||||||
HeapSnapshot* snapshot_;
|
HeapSnapshot* snapshot_;
|
||||||
v8::ActivityControl* control_;
|
v8::ActivityControl* control_;
|
||||||
HeapSnapshotsCollection* collection_;
|
V8HeapExplorer v8_heap_explorer_;
|
||||||
// Mapping from HeapObject* pointers to HeapEntry* pointers.
|
// Mapping from HeapThing pointers to HeapEntry* pointers.
|
||||||
HeapEntriesMap entries_;
|
HeapEntriesMap entries_;
|
||||||
SnapshotFillerInterface* filler_;
|
|
||||||
// Used during references extraction to mark heap objects that
|
|
||||||
// are references via non-hidden properties.
|
|
||||||
HeapObjectsSet known_references_;
|
|
||||||
// Used during snapshot generation.
|
// Used during snapshot generation.
|
||||||
int progress_counter_;
|
int progress_counter_;
|
||||||
int progress_total_;
|
int progress_total_;
|
||||||
|
|
||||||
friend class IndexedReferencesExtractor;
|
|
||||||
friend class RootsReferencesExtractor;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
|
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user