Commit 7b57b624 authored by alph@chromium.org's avatar alph@chromium.org

Heap snapshot: Update user roots definition.

Do not define an object as a user root if its context is not
present in Global handles.

R=mstarzinger@chromium.org, yurys@chromium.org

Review URL: https://codereview.chromium.org/17881005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15381 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e029039b
......@@ -961,7 +961,7 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
bool extract_indexed_refs = true;
if (obj->IsJSGlobalProxy()) {
ExtractJSGlobalProxyReferences(JSGlobalProxy::cast(obj));
ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj));
} else if (obj->IsJSObject()) {
ExtractJSObjectReferences(entry, JSObject::cast(obj));
} else if (obj->IsString()) {
......@@ -996,19 +996,11 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
}
void V8HeapExplorer::ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy) {
// We need to reference JS global objects from snapshot's root.
// We use JSGlobalProxy because this is what embedder (e.g. browser)
// uses for the global object.
Object* object = proxy->map()->prototype();
bool is_debug_object = false;
#ifdef ENABLE_DEBUGGER_SUPPORT
is_debug_object = object->IsGlobalObject() &&
Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object));
#endif
if (!is_debug_object) {
SetUserGlobalReference(object);
}
void V8HeapExplorer::ExtractJSGlobalProxyReferences(
int entry, JSGlobalProxy* proxy) {
SetInternalReference(proxy, entry,
"native_context", proxy->native_context(),
JSGlobalProxy::kNativeContextOffset);
}
......@@ -1778,6 +1770,22 @@ void V8HeapExplorer::SetGcSubrootReference(
snapshot_->gc_subroot(tag)->index(),
child_entry);
}
// Add a shortcut to JS global object reference at snapshot root.
if (child_obj->IsNativeContext()) {
Context* context = Context::cast(child_obj);
GlobalObject* global = context->global_object();
if (global->IsJSGlobalObject()) {
bool is_debug_object = false;
#ifdef ENABLE_DEBUGGER_SUPPORT
is_debug_object = heap_->isolate()->debug()->IsDebugGlobal(global);
#endif
if (!is_debug_object && !user_roots_.Contains(global)) {
user_roots_.Insert(global);
SetUserGlobalReference(global);
}
}
}
}
}
......
......@@ -454,7 +454,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
const char* GetSystemEntryName(HeapObject* object);
void ExtractReferences(HeapObject* obj);
void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy);
void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy);
void ExtractJSObjectReferences(int entry, JSObject* js_obj);
void ExtractStringReferences(int entry, String* obj);
void ExtractContextReferences(int entry, Context* context);
......@@ -532,6 +532,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
SnapshotFillerInterface* filler_;
HeapObjectsSet objects_tags_;
HeapObjectsSet strong_gc_subroot_names_;
HeapObjectsSet user_roots_;
v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_;
static HeapObject* const kGcRootsObject;
......
......@@ -92,8 +92,9 @@ class NamedEntriesDetector {
static const v8::HeapGraphNode* GetGlobalObject(
const v8::HeapSnapshot* snapshot) {
CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount());
// The 0th-child is (GC Roots), 1st is the user root.
const v8::HeapGraphNode* global_obj =
snapshot->GetRoot()->GetChild(0)->GetToNode();
snapshot->GetRoot()->GetChild(1)->GetToNode();
CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>(
reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6));
return global_obj;
......@@ -658,7 +659,8 @@ TEST(HeapSnapshotJSONSerialization) {
" first_edge_indexes[i] = first_edge_index;\n"
" first_edge_index += edge_fields_count *\n"
" parsed.nodes[i * node_fields_count + edge_count_offset];\n"
"}\n");
"}\n"
"first_edge_indexes[node_count] = first_edge_index;\n");
CHECK(!meta_analysis_result.IsEmpty());
// A helper function for processing encoded nodes.
......@@ -682,7 +684,7 @@ TEST(HeapSnapshotJSONSerialization) {
"GetChildPosByProperty(\n"
" GetChildPosByProperty(\n"
" GetChildPosByProperty("
" parsed.edges[edge_to_node_offset],"
" parsed.edges[edge_fields_count + edge_to_node_offset],"
" \"b\", property_type),\n"
" \"x\", property_type),"
" \"s\", property_type)");
......
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