Chromium Code Reviews| Index: src/heap-snapshot-generator.cc |
| diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc |
| index 10d113c3d17495aaada76aebd1bab8085ba9e0eb..4ddaf2d37af03164a43116c4b21ddfde65e2641d 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(); |
| + Object* shared_name = shared->DebugName(); |
|
alph
2013/10/31 12:55:46
nit: DebugName returns String, so you should not n
loislo
2013/10/31 14:41:14
Done.
|
| + const char* name = NULL; |
| + if (shared_name != *heap_->isolate()->factory()->empty_string()) { |
| + name = names->GetName(Name::cast(shared_name)); |
| + TagObject(shared->code(), names->GetFormatted("(code for %s)", name)); |
| + } else { |
| + TagObject(shared->code(), names->GetFormatted("(%s code)", |
| + Code::Kind2String(shared->code()->kind()))); |
|
yurys
2013/10/31 14:24:02
style: indent 4 characters
loislo
2013/10/31 14:41:14
Done.
|
| + } |
| + |
| 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,28 @@ void V8HeapExplorer::ExtractCodeCacheReferences( |
| } |
| +void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) { |
| + StringsStorage* names = collection_->names(); |
| + if (external_name) { |
| + TagObject(code, names->GetFormatted("(%s code)", external_name)); |
| + return; |
| + } |
| + switch (code->kind()) { |
| + case Code::STUB: { |
|
yurys
2013/10/31 14:24:02
if (code->kind() == Code::STUB) { would be more co
alph
2013/10/31 14:28:38
... and make the function overloaded ;-)
loislo
2013/10/31 14:41:14
Done.
loislo
2013/10/31 14:41:14
Done.
|
| + TagObject(code, names->GetFormatted("(%s code)", |
| + CodeStub::MajorName(static_cast<CodeStub::Major>(code->major_key()), |
| + true))); |
| + break; |
| + } |
| + default: { |
| + break; |
| + } |
| + } |
| +} |
| + |
| + |
| 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 +1733,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,23 +1751,33 @@ 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, prev_tag_index = 0; |
|
alph
2013/10/31 12:55:46
maybe prev_tag_index -> tag_first_index ?
|
| 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 |
| + && all_references_[all_index]->IsCode()) { |
|
yurys
2013/10/31 14:24:02
This should always be a code. But we can leave thi
loislo
2013/10/31 14:41:14
I'll make ASSERT(all_references_[all_index]->IsCod
|
| + explorer->TagCodeObject(Code::cast(all_references_[all_index]), |
| + builtins->name(all_index - prev_tag_index)); |
|
yurys
2013/10/31 14:24:02
Can we replace this prev_tag_index with builtin_in
alph
2013/10/31 14:28:38
I'd event move the increment inside if
loislo
2013/10/31 14:41:14
Done.
|
| + } |
| + ++all_index; |
| + if (reference_tags_[tags_index].index == all_index) { |
|
yurys
2013/10/31 14:24:02
As discussed offline this should be
while (refere
yurys
2013/11/01 14:55:04
On the second look the current implementation is c
|
| + prev_tag_index = all_index; |
| + ++tags_index; |
| } |
| - if (reference_tags_[tags_index].index == all_index) ++tags_index; |
| } |
| } |
| @@ -1746,6 +1795,7 @@ class RootsReferencesExtractor : public ObjectVisitor { |
| List<Object*> all_references_; |
| int previous_reference_count_; |
| List<IndexTag> reference_tags_; |
| + Heap* heap_; |
| }; |
| @@ -1771,7 +1821,7 @@ bool V8HeapExplorer::IterateAndExtractReferences( |
| } |
| SetRootGcRootsReference(); |
| - RootsReferencesExtractor extractor; |
| + RootsReferencesExtractor extractor(heap_); |
| heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
| extractor.SetCollectingAllReferences(); |
| heap_->IterateRoots(&extractor, VISIT_ALL); |