Index: src/heap-snapshot-generator.cc |
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc |
index 10d113c3d17495aaada76aebd1bab8085ba9e0eb..b7b7f2215b749f3830d555e3a0f43a20f8a30f20 100644 |
--- a/src/heap-snapshot-generator.cc |
+++ b/src/heap-snapshot-generator.cc |
@@ -30,6 +30,7 @@ |
#include "heap-snapshot-generator-inl.h" |
#include "allocation-tracker.h" |
+#include "code-stubs.h" |
#include "heap-profiler.h" |
#include "debug.h" |
#include "types.h" |
@@ -1110,7 +1111,7 @@ class IndexedReferencesExtractor : public ObjectVisitor { |
void VisitCodeEntry(Address entry_address) { |
Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); |
generator_->SetInternalReference(parent_obj_, parent_, "code", code); |
- generator_->TagObject(code, "(code)"); |
+ generator_->TagCodeObject(code); |
} |
void VisitPointers(Object** start, Object** end) { |
for (Object** p = start; p < end; p++) { |
@@ -1370,10 +1371,20 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) { |
void V8HeapExplorer::ExtractSharedFunctionInfoReferences( |
int entry, SharedFunctionInfo* shared) { |
HeapObject* obj = shared; |
+ StringsStorage* names = collection_->names(); |
+ String* shared_name = shared->DebugName(); |
+ const char* name = NULL; |
+ if (shared_name != *heap_->isolate()->factory()->empty_string()) { |
+ name = names->GetName(shared_name); |
+ TagObject(shared->code(), names->GetFormatted("(code for %s)", name)); |
+ } else { |
+ TagObject(shared->code(), names->GetFormatted("(%s code)", |
+ Code::Kind2String(shared->code()->kind()))); |
+ } |
+ |
SetInternalReference(obj, entry, |
"name", shared->name(), |
SharedFunctionInfo::kNameOffset); |
- TagObject(shared->code(), "(code)"); |
SetInternalReference(obj, entry, |
"code", shared->code(), |
SharedFunctionInfo::kCodeOffset); |
@@ -1387,7 +1398,10 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences( |
SetInternalReference(obj, entry, |
"script", shared->script(), |
SharedFunctionInfo::kScriptOffset); |
- TagObject(shared->construct_stub(), "(code)"); |
+ const char* construct_stub_name = name ? |
+ names->GetFormatted("(construct stub code for %s)", name) : |
+ "(construct stub code)"; |
+ TagObject(shared->construct_stub(), construct_stub_name); |
SetInternalReference(obj, entry, |
"construct_stub", shared->construct_stub(), |
SharedFunctionInfo::kConstructStubOffset); |
@@ -1400,6 +1414,9 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences( |
SetInternalReference(obj, entry, |
"inferred_name", shared->inferred_name(), |
SharedFunctionInfo::kInferredNameOffset); |
+ SetInternalReference(obj, entry, |
+ "optimized_code_map", shared->optimized_code_map(), |
+ SharedFunctionInfo::kOptimizedCodeMapOffset); |
SetWeakReference(obj, entry, |
1, shared->initial_map(), |
SharedFunctionInfo::kInitialMapOffset); |
@@ -1449,7 +1466,23 @@ void V8HeapExplorer::ExtractCodeCacheReferences( |
} |
+void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) { |
+ TagObject(code, collection_->names()->GetFormatted("(%s code)", |
+ external_name)); |
+} |
+ |
+ |
+void V8HeapExplorer::TagCodeObject(Code* code) { |
+ if (code->kind() == Code::STUB) { |
+ TagObject(code, collection_->names()->GetFormatted( |
+ "(%s code)", CodeStub::MajorName( |
+ static_cast<CodeStub::Major>(code->major_key()), true))); |
+ } |
+} |
+ |
+ |
void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) { |
+ TagCodeObject(code); |
TagObject(code->relocation_info(), "(code relocation info)"); |
SetInternalReference(code, entry, |
"relocation_info", code->relocation_info(), |
@@ -1695,9 +1728,10 @@ class RootsReferencesExtractor : public ObjectVisitor { |
}; |
public: |
- RootsReferencesExtractor() |
+ explicit RootsReferencesExtractor(Heap* heap) |
: collecting_all_references_(false), |
- previous_reference_count_(0) { |
+ previous_reference_count_(0), |
+ heap_(heap) { |
} |
void VisitPointers(Object** start, Object** end) { |
@@ -1712,22 +1746,30 @@ class RootsReferencesExtractor : public ObjectVisitor { |
void FillReferences(V8HeapExplorer* explorer) { |
ASSERT(strong_references_.length() <= all_references_.length()); |
+ Builtins* builtins = heap_->isolate()->builtins(); |
for (int i = 0; i < reference_tags_.length(); ++i) { |
explorer->SetGcRootsReference(reference_tags_[i].tag); |
} |
- int strong_index = 0, all_index = 0, tags_index = 0; |
+ int strong_index = 0, all_index = 0, tags_index = 0, builtin_index = 0; |
while (all_index < all_references_.length()) { |
if (strong_index < strong_references_.length() && |
strong_references_[strong_index] == all_references_[all_index]) { |
explorer->SetGcSubrootReference(reference_tags_[tags_index].tag, |
false, |
- all_references_[all_index++]); |
+ all_references_[all_index]); |
++strong_index; |
} else { |
explorer->SetGcSubrootReference(reference_tags_[tags_index].tag, |
true, |
- all_references_[all_index++]); |
+ all_references_[all_index]); |
+ } |
+ if (reference_tags_[tags_index].tag == |
+ VisitorSynchronization::kBuiltins) { |
+ ASSERT(all_references_[all_index]->IsCode()); |
+ explorer->TagCodeObject(Code::cast(all_references_[all_index]), |
+ builtins->name(builtin_index++)); |
} |
+ ++all_index; |
if (reference_tags_[tags_index].index == all_index) ++tags_index; |
} |
} |
@@ -1746,6 +1788,7 @@ class RootsReferencesExtractor : public ObjectVisitor { |
List<Object*> all_references_; |
int previous_reference_count_; |
List<IndexTag> reference_tags_; |
+ Heap* heap_; |
}; |
@@ -1771,7 +1814,7 @@ bool V8HeapExplorer::IterateAndExtractReferences( |
} |
SetRootGcRootsReference(); |
- RootsReferencesExtractor extractor; |
+ RootsReferencesExtractor extractor(heap_); |
heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
extractor.SetCollectingAllReferences(); |
heap_->IterateRoots(&extractor, VISIT_ALL); |