Show names for the strong roots in heap snapshot.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11392 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
alexeif@chromium.org 2012-04-19 15:58:42 +00:00
parent 60863e5cd6
commit 72a9e445e5
3 changed files with 59 additions and 4 deletions

View File

@ -2655,14 +2655,42 @@ void V8HeapExplorer::SetGcSubrootReference(
VisitorSynchronization::SyncTag tag, bool is_weak, Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetIndexedAutoIndexReference(
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement,
GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag),
child_obj, child_entry);
const char* name = GetStrongGcSubrootName(child_obj);
if (name != NULL) {
filler_->SetNamedReference(
HeapGraphEdge::kInternal,
GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag),
name,
child_obj, child_entry);
} else {
filler_->SetIndexedAutoIndexReference(
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement,
GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag),
child_obj, child_entry);
}
}
}
const char* V8HeapExplorer::GetStrongGcSubrootName(Object* object) {
if (strong_gc_subroot_names_.is_empty()) {
#define NAME_ENTRY(name) strong_gc_subroot_names_.SetTag(heap_->name(), #name);
#define ROOT_NAME(type, name, camel_name) NAME_ENTRY(name)
STRONG_ROOT_LIST(ROOT_NAME)
#undef ROOT_NAME
#define STRUCT_MAP_NAME(NAME, Name, name) NAME_ENTRY(name##_map)
STRUCT_LIST(STRUCT_MAP_NAME)
#undef STRUCT_MAP_NAME
#define SYMBOL_NAME(name, str) NAME_ENTRY(name)
SYMBOL_LIST(SYMBOL_NAME)
#undef SYMBOL_NAME
#undef NAME_ENTRY
CHECK(!strong_gc_subroot_names_.is_empty());
}
return strong_gc_subroot_names_.GetTag(object);
}
void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
if (obj->IsHeapObject() &&
!obj->IsOddball() &&

View File

@ -897,6 +897,7 @@ class HeapObjectsSet {
void Insert(Object* obj);
const char* GetTag(Object* obj);
void SetTag(Object* obj, const char* tag);
bool is_empty() const { return entries_.occupancy() == 0; }
private:
HashMap entries_;
@ -1025,6 +1026,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
void SetGcSubrootReference(
VisitorSynchronization::SyncTag tag, bool is_weak, Object* child);
const char* GetStrongGcSubrootName(Object* object);
void SetObjectName(HeapObject* object);
void TagObject(Object* obj, const char* tag);
@ -1039,6 +1041,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
SnapshottingProgressReportingInterface* progress_;
SnapshotFillerInterface* filler_;
HeapObjectsSet objects_tags_;
HeapObjectsSet strong_gc_subroot_names_;
static HeapObject* const kGcRootsObject;
static HeapObject* const kFirstGcSubrootObject;

View File

@ -4,6 +4,8 @@
#include "v8.h"
#include <ctype.h>
#include "cctest.h"
#include "heap-profiler.h"
#include "snapshot.h"
@ -1621,3 +1623,25 @@ TEST(PersistentHandleCount) {
p_BBB.Dispose();
CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount());
}
TEST(AllStrongGcRootsHaveNames) {
v8::HandleScope scope;
LocalContext env;
CompileRun("foo = {};");
const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(v8_str("snapshot"));
const v8::HeapGraphNode* gc_roots = GetNode(
snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)");
CHECK_NE(NULL, gc_roots);
const v8::HeapGraphNode* strong_roots = GetNode(
gc_roots, v8::HeapGraphNode::kObject, "(Strong roots)");
CHECK_NE(NULL, strong_roots);
for (int i = 0; i < strong_roots->GetChildrenCount(); ++i) {
const v8::HeapGraphEdge* edge = strong_roots->GetChild(i);
CHECK_EQ(v8::HeapGraphEdge::kInternal, edge->GetType());
v8::String::AsciiValue name(edge->GetName());
CHECK(isalpha(**name));
}
}