Reviewers: Yury Semikhatsky, alph, yangguo, Sven Panne,
Description:
HeapProfiler: provide human readable names for code objects.
It is very hard to understand the structure of the heap even for about:blank
page
because code objects in the heap have no names. This patch propagates the
names
for Code::STUB and Code::BUILTIN code objects.
Also it assign function names from SharedFunctionInfo to the code objects.
BUG=
Please review this at https://codereview.chromium.org/52643002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+69, -10 lines):
M src/builtins.h
M src/heap-snapshot-generator.h
M src/heap-snapshot-generator.cc
Index: src/builtins.h
diff --git a/src/builtins.h b/src/builtins.h
index
9b589d843de90960bb5fa432c50a8c80337c6237..2df4b186dbc90ae1dc7e2062c6046dc6d17a39e5
100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -364,6 +364,11 @@ class Builtins {
}
static const char* GetName(JavaScript id) { return
javascript_names_[id]; }
+ const char* name(int index) {
+ ASSERT(index >= 0);
+ ASSERT(index < id_count);
+ return names_[index];
+ }
static int GetArgumentsCount(JavaScript id) { return
javascript_argc_[id]; }
Handle<Code> GetCode(JavaScript id, bool* resolved);
static int NumberOfJavaScriptBuiltins() { return id_count; }
Index: src/heap-snapshot-generator.cc
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index
10d113c3d17495aaada76aebd1bab8085ba9e0eb..0d8c54b61857d8bb4fc9045eaba98c41bfc0d5ed
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++) {
@@ -1373,7 +1374,20 @@ void
V8HeapExplorer::ExtractSharedFunctionInfoReferences(
SetInternalReference(obj, entry,
"name", shared->name(),
SharedFunctionInfo::kNameOffset);
- TagObject(shared->code(), "(code)");
+ Object* empty_string = *heap_->isolate()->factory()->empty_string();
+ StringsStorage* names = collection_->names();
+ Object* shared_name = shared->name();
+ shared_name = !shared_name->IsFailure() ? shared_name :
shared->DebugName();
+ shared_name = !shared_name->IsFailure() ? shared_name :
+ shared->inferred_name();
+ const char* name = NULL;
+ if (shared_name != 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())));
+ }
SetInternalReference(obj, entry,
"code", shared->code(),
SharedFunctionInfo::kCodeOffset);
@@ -1387,7 +1401,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 +1417,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 +1469,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: {
+ 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 +1736,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 +1754,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;
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()) {
+ explorer->TagCodeObject(Code::cast(all_references_[all_index]),
+ builtins->name(all_index - prev_tag_index));
+ }
+ ++all_index;
+ if (reference_tags_[tags_index].index == all_index) {
+ prev_tag_index = all_index;
+ ++tags_index;
}
- if (reference_tags_[tags_index].index == all_index) ++tags_index;
}
}
@@ -1746,6 +1798,7 @@ class RootsReferencesExtractor : public ObjectVisitor
{
List<Object*> all_references_;
int previous_reference_count_;
List<IndexTag> reference_tags_;
+ Heap* heap_;
};
@@ -1771,7 +1824,7 @@ bool V8HeapExplorer::IterateAndExtractReferences(
}
SetRootGcRootsReference();
- RootsReferencesExtractor extractor;
+ RootsReferencesExtractor extractor(heap_);
heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG);
extractor.SetCollectingAllReferences();
heap_->IterateRoots(&extractor, VISIT_ALL);
Index: src/heap-snapshot-generator.h
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index
e4038b10f43cc51f36fa81d250427775b980dce7..45491981127845e46be6f188e33c2ee671d6e8cc
100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -447,6 +447,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
int EstimateObjectsCount(HeapIterator* iterator);
bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
void TagGlobalObjects();
+ void TagCodeObject(Code* code, const char* external_name = NULL);
static String* GetConstructorName(JSObject* object);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.