Commit dc3f16a3 authored by loislo@chromium.org's avatar loislo@chromium.org

I will apply it to the nodes that can't be mapped to Heap object or Native object.

As example there are 'Detached DOM Tree' nodes in WebKit. It is very useful to be able to see all such
nodes grouped together. It can be done with help of some post processing but I did this explicitly
on v8 side because it is much faster. At the moment this kind of nodes has kNative type.
I'd like to hide these nodes from the Retainment View but I can filter them only by name.

BUG=none
TEST=HeapSnapshotRetainedObjectInfo

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10614 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 08bed81f
...@@ -255,7 +255,9 @@ class V8EXPORT HeapGraphNode { ...@@ -255,7 +255,9 @@ class V8EXPORT HeapGraphNode {
kClosure = 5, // Function closure. kClosure = 5, // Function closure.
kRegExp = 6, // RegExp. kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap. kHeapNumber = 7, // Number stored in the heap.
kNative = 8 // Native object (not from V8 heap). kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9 // Synthetic object, usualy used for grouping
// snapshot items together.
}; };
/** Returns node type (see HeapGraphNode::Type). */ /** Returns node type (see HeapGraphNode::Type). */
......
...@@ -1131,6 +1131,7 @@ const char* HeapEntry::TypeAsString() { ...@@ -1131,6 +1131,7 @@ const char* HeapEntry::TypeAsString() {
case kRegExp: return "/regexp/"; case kRegExp: return "/regexp/";
case kHeapNumber: return "/number/"; case kHeapNumber: return "/number/";
case kNative: return "/native/"; case kNative: return "/native/";
case kSynthetic: return "/synthetic/";
default: return "???"; default: return "???";
} }
} }
...@@ -2698,6 +2699,45 @@ class GlobalHandlesExtractor : public ObjectVisitor { ...@@ -2698,6 +2699,45 @@ class GlobalHandlesExtractor : public ObjectVisitor {
NativeObjectsExplorer* explorer_; NativeObjectsExplorer* explorer_;
}; };
class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
public:
BasicHeapEntriesAllocator(
HeapSnapshot* snapshot,
HeapEntry::Type entries_type)
: snapshot_(snapshot),
collection_(snapshot_->collection()),
entries_type_(entries_type) {
}
virtual HeapEntry* AllocateEntry(
HeapThing ptr, int children_count, int retainers_count);
private:
HeapSnapshot* snapshot_;
HeapSnapshotsCollection* collection_;
HeapEntry::Type entries_type_;
};
HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(
HeapThing ptr, int children_count, int retainers_count) {
v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
intptr_t elements = info->GetElementCount();
intptr_t size = info->GetSizeInBytes();
return snapshot_->AddEntry(
entries_type_,
elements != -1 ?
collection_->names()->GetFormatted(
"%s / %" V8_PTR_PREFIX "d entries",
info->GetLabel(),
info->GetElementCount()) :
collection_->names()->GetCopy(info->GetLabel()),
HeapObjectsMap::GenerateId(info),
size != -1 ? static_cast<int>(size) : 0,
children_count,
retainers_count);
}
NativeObjectsExplorer::NativeObjectsExplorer( NativeObjectsExplorer::NativeObjectsExplorer(
HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress)
: snapshot_(snapshot), : snapshot_(snapshot),
...@@ -2707,6 +2747,10 @@ NativeObjectsExplorer::NativeObjectsExplorer( ...@@ -2707,6 +2747,10 @@ NativeObjectsExplorer::NativeObjectsExplorer(
objects_by_info_(RetainedInfosMatch), objects_by_info_(RetainedInfosMatch),
native_groups_(StringsMatch), native_groups_(StringsMatch),
filler_(NULL) { filler_(NULL) {
synthetic_entries_allocator_ =
new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic);
native_entries_allocator_ =
new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative);
} }
...@@ -2728,27 +2772,8 @@ NativeObjectsExplorer::~NativeObjectsExplorer() { ...@@ -2728,27 +2772,8 @@ NativeObjectsExplorer::~NativeObjectsExplorer() {
reinterpret_cast<v8::RetainedObjectInfo*>(p->value); reinterpret_cast<v8::RetainedObjectInfo*>(p->value);
info->Dispose(); info->Dispose();
} }
} delete synthetic_entries_allocator_;
delete native_entries_allocator_;
HeapEntry* NativeObjectsExplorer::AllocateEntry(
HeapThing ptr, int children_count, int retainers_count) {
v8::RetainedObjectInfo* info =
reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
intptr_t elements = info->GetElementCount();
intptr_t size = info->GetSizeInBytes();
return snapshot_->AddEntry(
HeapEntry::kNative,
elements != -1 ?
collection_->names()->GetFormatted(
"%s / %" V8_PTR_PREFIX "d entries",
info->GetLabel(),
info->GetElementCount()) :
collection_->names()->GetCopy(info->GetLabel()),
HeapObjectsMap::GenerateId(info),
size != -1 ? static_cast<int>(size) : 0,
children_count,
retainers_count);
} }
...@@ -2790,12 +2815,14 @@ void NativeObjectsExplorer::FillImplicitReferences() { ...@@ -2790,12 +2815,14 @@ void NativeObjectsExplorer::FillImplicitReferences() {
for (int i = 0; i < groups->length(); ++i) { for (int i = 0; i < groups->length(); ++i) {
ImplicitRefGroup* group = groups->at(i); ImplicitRefGroup* group = groups->at(i);
HeapObject* parent = *group->parent_; HeapObject* parent = *group->parent_;
HeapEntry* parent_entry = filler_->FindOrAddEntry(parent, this); HeapEntry* parent_entry =
filler_->FindOrAddEntry(parent, native_entries_allocator_);
ASSERT(parent_entry != NULL); ASSERT(parent_entry != NULL);
Object*** children = group->children_; Object*** children = group->children_;
for (size_t j = 0; j < group->length_; ++j) { for (size_t j = 0; j < group->length_; ++j) {
Object* child = *children[j]; Object* child = *children[j];
HeapEntry* child_entry = filler_->FindOrAddEntry(child, this); HeapEntry* child_entry =
filler_->FindOrAddEntry(child, native_entries_allocator_);
filler_->SetNamedReference( filler_->SetNamedReference(
HeapGraphEdge::kInternal, HeapGraphEdge::kInternal,
parent, parent_entry, parent, parent_entry,
...@@ -2886,11 +2913,13 @@ NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( ...@@ -2886,11 +2913,13 @@ NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
void NativeObjectsExplorer::SetNativeRootReference( void NativeObjectsExplorer::SetNativeRootReference(
v8::RetainedObjectInfo* info) { v8::RetainedObjectInfo* info) {
HeapEntry* child_entry = filler_->FindOrAddEntry(info, this); HeapEntry* child_entry =
filler_->FindOrAddEntry(info, native_entries_allocator_);
ASSERT(child_entry != NULL); ASSERT(child_entry != NULL);
NativeGroupRetainedObjectInfo* group_info = NativeGroupRetainedObjectInfo* group_info =
FindOrAddGroupInfo(info->GetGroupLabel()); FindOrAddGroupInfo(info->GetGroupLabel());
HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); HeapEntry* group_entry =
filler_->FindOrAddEntry(group_info, synthetic_entries_allocator_);
filler_->SetNamedAutoIndexReference( filler_->SetNamedAutoIndexReference(
HeapGraphEdge::kInternal, HeapGraphEdge::kInternal,
group_info, group_entry, group_info, group_entry,
...@@ -2902,7 +2931,8 @@ void NativeObjectsExplorer::SetWrapperNativeReferences( ...@@ -2902,7 +2931,8 @@ void NativeObjectsExplorer::SetWrapperNativeReferences(
HeapObject* wrapper, v8::RetainedObjectInfo* info) { HeapObject* wrapper, v8::RetainedObjectInfo* info) {
HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
ASSERT(wrapper_entry != NULL); ASSERT(wrapper_entry != NULL);
HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); HeapEntry* info_entry =
filler_->FindOrAddEntry(info, native_entries_allocator_);
ASSERT(info_entry != NULL); ASSERT(info_entry != NULL);
filler_->SetNamedReference(HeapGraphEdge::kInternal, filler_->SetNamedReference(HeapGraphEdge::kInternal,
wrapper, wrapper_entry, wrapper, wrapper_entry,
...@@ -2920,7 +2950,8 @@ void NativeObjectsExplorer::SetRootNativeRootsReference() { ...@@ -2920,7 +2950,8 @@ void NativeObjectsExplorer::SetRootNativeRootsReference() {
entry = native_groups_.Next(entry)) { entry = native_groups_.Next(entry)) {
NativeGroupRetainedObjectInfo* group_info = NativeGroupRetainedObjectInfo* group_info =
static_cast<NativeGroupRetainedObjectInfo*>(entry->value); static_cast<NativeGroupRetainedObjectInfo*>(entry->value);
HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); HeapEntry* group_entry =
filler_->FindOrAddEntry(group_info, native_entries_allocator_);
ASSERT(group_entry != NULL); ASSERT(group_entry != NULL);
filler_->SetIndexedAutoIndexReference( filler_->SetIndexedAutoIndexReference(
HeapGraphEdge::kElement, HeapGraphEdge::kElement,
...@@ -3547,7 +3578,8 @@ void HeapSnapshotJSONSerializer::SerializeNodes() { ...@@ -3547,7 +3578,8 @@ void HeapSnapshotJSONSerializer::SerializeNodes() {
"," JSON_S("closure") "," JSON_S("closure")
"," JSON_S("regexp") "," JSON_S("regexp")
"," JSON_S("number") "," JSON_S("number")
"," JSON_S("native")) "," JSON_S("native")
"," JSON_S("synthetic"))
"," JSON_S("string") "," JSON_S("string")
"," JSON_S("number") "," JSON_S("number")
"," JSON_S("number") "," JSON_S("number")
......
...@@ -525,7 +525,8 @@ class HeapEntry BASE_EMBEDDED { ...@@ -525,7 +525,8 @@ class HeapEntry BASE_EMBEDDED {
kClosure = v8::HeapGraphNode::kClosure, kClosure = v8::HeapGraphNode::kClosure,
kRegExp = v8::HeapGraphNode::kRegExp, kRegExp = v8::HeapGraphNode::kRegExp,
kHeapNumber = v8::HeapGraphNode::kHeapNumber, kHeapNumber = v8::HeapGraphNode::kHeapNumber,
kNative = v8::HeapGraphNode::kNative kNative = v8::HeapGraphNode::kNative,
kSynthetic = v8::HeapGraphNode::kSynthetic
}; };
HeapEntry() { } HeapEntry() { }
...@@ -1026,16 +1027,16 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -1026,16 +1027,16 @@ class V8HeapExplorer : public HeapEntriesAllocator {
DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer); DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer);
}; };
class NativeGroupRetainedObjectInfo; class NativeGroupRetainedObjectInfo;
// An implementation of retained native objects extractor. // An implementation of retained native objects extractor.
class NativeObjectsExplorer : public HeapEntriesAllocator { class NativeObjectsExplorer {
public: public:
NativeObjectsExplorer(HeapSnapshot* snapshot, NativeObjectsExplorer(HeapSnapshot* snapshot,
SnapshottingProgressReportingInterface* progress); SnapshottingProgressReportingInterface* progress);
virtual ~NativeObjectsExplorer(); virtual ~NativeObjectsExplorer();
virtual HeapEntry* AllocateEntry(
HeapThing ptr, int children_count, int retainers_count);
void AddRootEntries(SnapshotFillerInterface* filler); void AddRootEntries(SnapshotFillerInterface* filler);
int EstimateObjectsCount(); int EstimateObjectsCount();
bool IterateAndExtractReferences(SnapshotFillerInterface* filler); bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
...@@ -1074,6 +1075,8 @@ class NativeObjectsExplorer : public HeapEntriesAllocator { ...@@ -1074,6 +1075,8 @@ class NativeObjectsExplorer : public HeapEntriesAllocator {
// RetainedObjectInfo* -> List<HeapObject*>* // RetainedObjectInfo* -> List<HeapObject*>*
HashMap objects_by_info_; HashMap objects_by_info_;
HashMap native_groups_; HashMap native_groups_;
HeapEntriesAllocator* synthetic_entries_allocator_;
HeapEntriesAllocator* native_entries_allocator_;
// Used during references extraction. // Used during references extraction.
SnapshotFillerInterface* filler_; SnapshotFillerInterface* filler_;
......
...@@ -774,7 +774,7 @@ TEST(HeapSnapshotRetainedObjectInfo) { ...@@ -774,7 +774,7 @@ TEST(HeapSnapshotRetainedObjectInfo) {
} }
const v8::HeapGraphNode* native_group_aaa = GetNode( const v8::HeapGraphNode* native_group_aaa = GetNode(
snapshot->GetRoot(), v8::HeapGraphNode::kNative, "aaa-group"); snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "aaa-group");
CHECK_NE(NULL, native_group_aaa); CHECK_NE(NULL, native_group_aaa);
CHECK_EQ(1, native_group_aaa->GetChildrenCount()); CHECK_EQ(1, native_group_aaa->GetChildrenCount());
const v8::HeapGraphNode* aaa = GetNode( const v8::HeapGraphNode* aaa = GetNode(
...@@ -783,7 +783,7 @@ TEST(HeapSnapshotRetainedObjectInfo) { ...@@ -783,7 +783,7 @@ TEST(HeapSnapshotRetainedObjectInfo) {
CHECK_EQ(2, aaa->GetChildrenCount()); CHECK_EQ(2, aaa->GetChildrenCount());
const v8::HeapGraphNode* native_group_ccc = GetNode( const v8::HeapGraphNode* native_group_ccc = GetNode(
snapshot->GetRoot(), v8::HeapGraphNode::kNative, "ccc-group"); snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "ccc-group");
const v8::HeapGraphNode* ccc = GetNode( const v8::HeapGraphNode* ccc = GetNode(
native_group_ccc, v8::HeapGraphNode::kNative, "ccc"); native_group_ccc, v8::HeapGraphNode::kNative, "ccc");
CHECK_NE(NULL, ccc); CHECK_NE(NULL, ccc);
......
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