Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Unified Diff: src/profile-generator.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profile-generator.cc
===================================================================
--- src/profile-generator.cc (revision 7006)
+++ src/profile-generator.cc (working copy)
@@ -158,13 +158,18 @@
uint32_t CodeEntry::GetCallUid() const {
uint32_t hash = ComputeIntegerHash(tag_);
- hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)));
- hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
- hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)));
- hash ^= ComputeIntegerHash(line_number_);
+ if (shared_id_ != 0) {
+ hash ^= ComputeIntegerHash(
+ static_cast<uint32_t>(shared_id_));
+ } else {
+ hash ^= ComputeIntegerHash(
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)));
+ hash ^= ComputeIntegerHash(
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
+ hash ^= ComputeIntegerHash(
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)));
+ hash ^= ComputeIntegerHash(line_number_);
+ }
return hash;
}
@@ -172,10 +177,12 @@
bool CodeEntry::IsSameAs(CodeEntry* entry) const {
return this == entry
|| (tag_ == entry->tag_
- && name_prefix_ == entry->name_prefix_
- && name_ == entry->name_
- && resource_name_ == entry->resource_name_
- && line_number_ == entry->line_number_);
+ && shared_id_ == entry->shared_id_
+ && (shared_id_ != 0
+ || (name_prefix_ == entry->name_prefix_
+ && name_ == entry->name_
+ && resource_name_ == entry->resource_name_
+ && line_number_ == entry->line_number_)));
}
@@ -460,23 +467,12 @@
}
+CodeEntry* const CodeMap::kSfiCodeEntry = NULL;
const CodeMap::CodeTreeConfig::Key CodeMap::CodeTreeConfig::kNoKey = NULL;
const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue =
CodeMap::CodeEntryInfo(NULL, 0);
-void CodeMap::AddAlias(Address start, CodeEntry* entry, Address code_start) {
- CodeTree::Locator locator;
- if (tree_.Find(code_start, &locator)) {
- const CodeEntryInfo& code_info = locator.value();
- if (tree_.Insert(start, &locator)) {
- entry->CopyData(*code_info.entry);
- locator.set_value(CodeEntryInfo(entry, code_info.size));
- }
- }
-}
-
-
CodeEntry* CodeMap::FindEntry(Address addr) {
CodeTree::Locator locator;
if (tree_.FindGreatestLessThan(addr, &locator)) {
@@ -489,6 +485,22 @@
}
+int CodeMap::GetSFITag(Address addr) {
+ CodeTree::Locator locator;
+ // For SFI entries, 'size' field is used to store their IDs.
+ if (tree_.Find(addr, &locator)) {
+ const CodeEntryInfo& entry = locator.value();
+ ASSERT(entry.entry == kSfiCodeEntry);
+ return entry.size;
+ } else {
+ tree_.Insert(addr, &locator);
+ int tag = next_sfi_tag_++;
+ locator.set_value(CodeEntryInfo(kSfiCodeEntry, tag));
+ return tag;
+ }
+}
+
+
void CodeMap::CodeTreePrinter::Call(
const Address& key, const CodeMap::CodeEntryInfo& value) {
OS::Print("%p %5d %s\n", key, value.size, value.entry->name());
@@ -717,13 +729,6 @@
}
-CodeEntry* CpuProfilesCollection::NewCodeEntry(int security_token_id) {
- CodeEntry* entry = new CodeEntry(security_token_id);
- code_entries_.Add(entry);
- return entry;
-}
-
-
void CpuProfilesCollection::AddPathToCurrentProfiles(
const Vector<CodeEntry*>& path) {
// As starting / stopping profiles is rare relatively to this
@@ -788,19 +793,10 @@
if (sample.pc != NULL) {
*entry++ = code_map_.FindEntry(sample.pc);
- if (sample.function != NULL) {
- *entry = code_map_.FindEntry(sample.function);
+ if (sample.tos != NULL) {
+ *entry = code_map_.FindEntry(sample.tos);
if (*entry != NULL && !(*entry)->is_js_function()) {
*entry = NULL;
- } else {
- CodeEntry* pc_entry = *entries.start();
- if (pc_entry == NULL) {
- *entry = NULL;
- } else if (pc_entry->is_js_function()) {
- // Use function entry in favor of pc entry, as function
- // entry has security token.
- *entries.start() = NULL;
- }
}
entry++;
}
@@ -1185,12 +1181,6 @@
}
-HeapObject *const HeapSnapshot::kInternalRootObject =
- reinterpret_cast<HeapObject*>(1);
-HeapObject *const HeapSnapshot::kGcRootsObject =
- reinterpret_cast<HeapObject*>(2);
-
-
// It is very important to keep objects that form a heap snapshot
// as small as possible.
namespace { // Avoid littering the global namespace.
@@ -1261,96 +1251,6 @@
}
-HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
- int children_count,
- int retainers_count) {
- if (object == kInternalRootObject) {
- ASSERT(root_entry_ == NULL);
- ASSERT(retainers_count == 0);
- return (root_entry_ = AddEntry(HeapEntry::kObject,
- "",
- HeapObjectsMap::kInternalRootObjectId,
- 0,
- children_count,
- retainers_count));
- } else if (object == kGcRootsObject) {
- ASSERT(gc_roots_entry_ == NULL);
- return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
- "(GC roots)",
- HeapObjectsMap::kGcRootsObjectId,
- 0,
- children_count,
- retainers_count));
- } else if (object->IsJSFunction()) {
- JSFunction* func = JSFunction::cast(object);
- SharedFunctionInfo* shared = func->shared();
- return AddEntry(object,
- HeapEntry::kClosure,
- collection_->GetName(String::cast(shared->name())),
- children_count,
- retainers_count);
- } else if (object->IsJSRegExp()) {
- JSRegExp* re = JSRegExp::cast(object);
- return AddEntry(object,
- HeapEntry::kRegExp,
- collection_->GetName(re->Pattern()),
- children_count,
- retainers_count);
- } else if (object->IsJSObject()) {
- return AddEntry(object,
- HeapEntry::kObject,
- collection_->GetName(GetConstructorNameForHeapProfile(
- JSObject::cast(object))),
- children_count,
- retainers_count);
- } else if (object->IsString()) {
- return AddEntry(object,
- HeapEntry::kString,
- collection_->GetName(String::cast(object)),
- children_count,
- retainers_count);
- } else if (object->IsCode()) {
- return AddEntry(object,
- HeapEntry::kCode,
- "",
- children_count,
- retainers_count);
- } else if (object->IsSharedFunctionInfo()) {
- SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
- return AddEntry(object,
- HeapEntry::kCode,
- collection_->GetName(String::cast(shared->name())),
- children_count,
- retainers_count);
- } else if (object->IsScript()) {
- Script* script = Script::cast(object);
- return AddEntry(object,
- HeapEntry::kCode,
- script->name()->IsString() ?
- collection_->GetName(String::cast(script->name())) : "",
- children_count,
- retainers_count);
- } else if (object->IsFixedArray()) {
- return AddEntry(object,
- HeapEntry::kArray,
- "",
- children_count,
- retainers_count);
- } else if (object->IsHeapNumber()) {
- return AddEntry(object,
- HeapEntry::kHeapNumber,
- "number",
- children_count,
- retainers_count);
- }
- return AddEntry(object,
- HeapEntry::kHidden,
- "system",
- children_count,
- retainers_count);
-}
-
-
static void HeapEntryClearPaint(HeapEntry** entry_ptr) {
(*entry_ptr)->clear_paint();
}
@@ -1360,20 +1260,29 @@
}
-HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
- HeapEntry::Type type,
- const char* name,
- int children_count,
- int retainers_count) {
- return AddEntry(type,
- name,
- collection_->GetObjectId(object->address()),
- object->Size(),
- children_count,
- retainers_count);
+HeapEntry* HeapSnapshot::AddRootEntry(int children_count) {
+ ASSERT(root_entry_ == NULL);
+ return (root_entry_ = AddEntry(HeapEntry::kObject,
+ "",
+ HeapObjectsMap::kInternalRootObjectId,
+ 0,
+ children_count,
+ 0));
}
+HeapEntry* HeapSnapshot::AddGcRootsEntry(int children_count,
+ int retainers_count) {
+ ASSERT(gc_roots_entry_ == NULL);
+ return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
+ "(GC roots)",
+ HeapObjectsMap::kGcRootsObjectId,
+ 0,
+ children_count,
+ retainers_count));
+}
+
+
HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
const char* name,
uint64_t id,
@@ -1623,7 +1532,7 @@
reinterpret_cast<HeapEntry*>(1);
HeapEntriesMap::HeapEntriesMap()
- : entries_(HeapObjectsMatch),
+ : entries_(HeapThingsMatch),
entries_count_(0),
total_children_count_(0),
total_retainers_count_(0) {
@@ -1637,8 +1546,23 @@
}
-HeapEntry* HeapEntriesMap::Map(HeapObject* object) {
- HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), false);
+void HeapEntriesMap::AllocateEntries() {
+ for (HashMap::Entry* p = entries_.Start();
+ p != NULL;
+ p = entries_.Next(p)) {
+ EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
+ entry_info->entry = entry_info->allocator->AllocateEntry(
+ p->key,
+ entry_info->children_count,
+ entry_info->retainers_count);
+ entry_info->children_count = 0;
+ entry_info->retainers_count = 0;
+ }
+}
+
+
+HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
+ HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
if (cache_entry != NULL) {
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
return entry_info->entry;
@@ -1648,15 +1572,16 @@
}
-void HeapEntriesMap::Pair(HeapObject* object, HeapEntry* entry) {
- HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), true);
+void HeapEntriesMap::Pair(
+ HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry) {
+ HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
ASSERT(cache_entry->value == NULL);
- cache_entry->value = new EntryInfo(entry);
+ cache_entry->value = new EntryInfo(entry, allocator);
++entries_count_;
}
-void HeapEntriesMap::CountReference(HeapObject* from, HeapObject* to,
+void HeapEntriesMap::CountReference(HeapThing from, HeapThing to,
int* prev_children_count,
int* prev_retainers_count) {
HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false);
@@ -1679,7 +1604,7 @@
HeapObjectsSet::HeapObjectsSet()
- : entries_(HeapEntriesMap::HeapObjectsMatch) {
+ : entries_(HeapEntriesMap::HeapThingsMatch) {
}
@@ -1708,206 +1633,144 @@
}
-HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
- v8::ActivityControl* control)
+HeapObject *const V8HeapExplorer::kInternalRootObject =
+ reinterpret_cast<HeapObject*>(1);
+HeapObject *const V8HeapExplorer::kGcRootsObject =
+ reinterpret_cast<HeapObject*>(2);
+
+
+V8HeapExplorer::V8HeapExplorer(
+ HeapSnapshot* snapshot,
+ SnapshottingProgressReportingInterface* progress)
: snapshot_(snapshot),
- control_(control),
- collection_(snapshot->collection()),
+ collection_(snapshot_->collection()),
+ progress_(progress),
filler_(NULL) {
}
-class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface {
- public:
- explicit SnapshotCounter(HeapEntriesMap* entries)
- : entries_(entries) { }
- HeapEntry* AddEntry(HeapObject* obj) {
- entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder);
- return HeapEntriesMap::kHeapEntryPlaceholder;
- }
- void SetIndexedReference(HeapGraphEdge::Type,
- HeapObject* parent_obj,
- HeapEntry*,
- int,
- Object* child_obj,
- HeapEntry*) {
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
- }
- void SetNamedReference(HeapGraphEdge::Type,
- HeapObject* parent_obj,
- HeapEntry*,
- const char*,
- Object* child_obj,
- HeapEntry*) {
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
- }
- void SetRootShortcutReference(Object* child_obj, HeapEntry*) {
- entries_->CountReference(
- HeapSnapshot::kInternalRootObject, HeapObject::cast(child_obj));
- }
- void SetRootGcRootsReference() {
- entries_->CountReference(
- HeapSnapshot::kInternalRootObject, HeapSnapshot::kGcRootsObject);
- }
- void SetStrongRootReference(Object* child_obj, HeapEntry*) {
- entries_->CountReference(
- HeapSnapshot::kGcRootsObject, HeapObject::cast(child_obj));
- }
- private:
- HeapEntriesMap* entries_;
-};
+V8HeapExplorer::~V8HeapExplorer() {
+}
-class SnapshotFiller : public HeapSnapshotGenerator::SnapshotFillerInterface {
- public:
- explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
- : snapshot_(snapshot),
- collection_(snapshot->collection()),
- entries_(entries) { }
- HeapEntry* AddEntry(HeapObject* obj) {
- UNREACHABLE();
- return NULL;
- }
- void SetIndexedReference(HeapGraphEdge::Type type,
- HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(parent_obj,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- parent_entry->SetIndexedReference(
- type, child_index, index, child_entry, retainer_index);
- }
- void SetNamedReference(HeapGraphEdge::Type type,
- HeapObject* parent_obj,
- HeapEntry* parent_entry,
- const char* reference_name,
- Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj),
- &child_index, &retainer_index);
- parent_entry->SetNamedReference(type,
- child_index,
- reference_name,
- child_entry,
- retainer_index);
- }
- void SetRootGcRootsReference() {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kInternalRootObject,
- HeapSnapshot::kGcRootsObject,
- &child_index,
- &retainer_index);
- snapshot_->root()->SetIndexedReference(HeapGraphEdge::kElement,
- child_index,
- child_index + 1,
- snapshot_->gc_roots(),
- retainer_index);
- }
- void SetRootShortcutReference(Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kInternalRootObject,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- snapshot_->root()->SetNamedReference(HeapGraphEdge::kShortcut,
- child_index,
- collection_->GetName(child_index + 1),
- child_entry,
- retainer_index);
- }
- void SetStrongRootReference(Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kGcRootsObject,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- snapshot_->gc_roots()->SetIndexedReference(HeapGraphEdge::kElement,
- child_index,
- child_index + 1,
- child_entry,
- retainer_index);
- }
- private:
- HeapSnapshot* snapshot_;
- HeapSnapshotsCollection* collection_;
- HeapEntriesMap* entries_;
-};
-class SnapshotAllocator {
- public:
- explicit SnapshotAllocator(HeapSnapshot* snapshot)
- : snapshot_(snapshot) { }
- HeapEntry* GetEntry(
- HeapObject* obj, int children_count, int retainers_count) {
- HeapEntry* entry =
- snapshot_->AddEntry(obj, children_count, retainers_count);
- ASSERT(entry != NULL);
- return entry;
- }
- private:
- HeapSnapshot* snapshot_;
-};
+HeapEntry* V8HeapExplorer::AllocateEntry(
+ HeapThing ptr, int children_count, int retainers_count) {
+ return AddEntry(
+ reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
+}
-class RootsReferencesExtractor : public ObjectVisitor {
- public:
- explicit RootsReferencesExtractor(HeapSnapshotGenerator* generator)
- : generator_(generator) {
+
+HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
+ int children_count,
+ int retainers_count) {
+ if (object == kInternalRootObject) {
+ ASSERT(retainers_count == 0);
+ return snapshot_->AddRootEntry(children_count);
+ } else if (object == kGcRootsObject) {
+ return snapshot_->AddGcRootsEntry(children_count, retainers_count);
+ } else if (object->IsJSFunction()) {
+ JSFunction* func = JSFunction::cast(object);
+ SharedFunctionInfo* shared = func->shared();
+ return AddEntry(object,
+ HeapEntry::kClosure,
+ collection_->GetName(String::cast(shared->name())),
+ children_count,
+ retainers_count);
+ } else if (object->IsJSRegExp()) {
+ JSRegExp* re = JSRegExp::cast(object);
+ return AddEntry(object,
+ HeapEntry::kRegExp,
+ collection_->GetName(re->Pattern()),
+ children_count,
+ retainers_count);
+ } else if (object->IsJSObject()) {
+ return AddEntry(object,
+ HeapEntry::kObject,
+ collection_->GetName(GetConstructorNameForHeapProfile(
+ JSObject::cast(object))),
+ children_count,
+ retainers_count);
+ } else if (object->IsString()) {
+ return AddEntry(object,
+ HeapEntry::kString,
+ collection_->GetName(String::cast(object)),
+ children_count,
+ retainers_count);
+ } else if (object->IsCode()) {
+ return AddEntry(object,
+ HeapEntry::kCode,
+ "",
+ children_count,
+ retainers_count);
+ } else if (object->IsSharedFunctionInfo()) {
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+ return AddEntry(object,
+ HeapEntry::kCode,
+ collection_->GetName(String::cast(shared->name())),
+ children_count,
+ retainers_count);
+ } else if (object->IsScript()) {
+ Script* script = Script::cast(object);
+ return AddEntry(object,
+ HeapEntry::kCode,
+ script->name()->IsString() ?
+ collection_->GetName(String::cast(script->name())) : "",
+ children_count,
+ retainers_count);
+ } else if (object->IsFixedArray()) {
+ return AddEntry(object,
+ HeapEntry::kArray,
+ "",
+ children_count,
+ retainers_count);
+ } else if (object->IsHeapNumber()) {
+ return AddEntry(object,
+ HeapEntry::kHeapNumber,
+ "number",
+ children_count,
+ retainers_count);
}
- void VisitPointers(Object** start, Object** end) {
- for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p);
- }
- private:
- HeapSnapshotGenerator* generator_;
-};
+ return AddEntry(object,
+ HeapEntry::kHidden,
+ "system",
+ children_count,
+ retainers_count);
+}
-bool HeapSnapshotGenerator::GenerateSnapshot() {
- AssertNoAllocation no_alloc;
+HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
+ HeapEntry::Type type,
+ const char* name,
+ int children_count,
+ int retainers_count) {
+ return snapshot_->AddEntry(type,
+ name,
+ collection_->GetObjectId(object->address()),
+ object->Size(),
+ children_count,
+ retainers_count);
+}
- SetProgressTotal(4); // 2 passes + dominators + sizes.
- // Pass 1. Iterate heap contents to count entries and references.
- if (!CountEntriesAndReferences()) return false;
-
- // Allocate and fill entries in the snapshot, allocate references.
- snapshot_->AllocateEntries(entries_.entries_count(),
- entries_.total_children_count(),
- entries_.total_retainers_count());
- SnapshotAllocator allocator(snapshot_);
- entries_.UpdateEntries(&allocator);
-
- // Pass 2. Fill references.
- if (!FillReferences()) return false;
-
- if (!SetEntriesDominators()) return false;
- if (!ApproximateRetainedSizes()) return false;
-
- progress_counter_ = progress_total_;
- if (!ReportProgress(true)) return false;
- return true;
+void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
+ filler->AddEntry(kInternalRootObject);
+ filler->AddEntry(kGcRootsObject);
}
-HeapEntry* HeapSnapshotGenerator::GetEntry(Object* obj) {
- if (!obj->IsHeapObject()) return NULL;
- HeapObject* object = HeapObject::cast(obj);
- HeapEntry* entry = entries_.Map(object);
- // A new entry.
- if (entry == NULL) entry = filler_->AddEntry(object);
- return entry;
+int V8HeapExplorer::EstimateObjectsCount() {
+ HeapIterator iterator(HeapIterator::kFilterUnreachable);
+ int objects_count = 0;
+ for (HeapObject* obj = iterator.next();
+ obj != NULL;
+ obj = iterator.next(), ++objects_count) {}
+ return objects_count;
}
class IndexedReferencesExtractor : public ObjectVisitor {
public:
- IndexedReferencesExtractor(HeapSnapshotGenerator* generator,
+ IndexedReferencesExtractor(V8HeapExplorer* generator,
HeapObject* parent_obj,
HeapEntry* parent_entry,
HeapObjectsSet* known_references = NULL)
@@ -1925,7 +1788,7 @@
}
}
private:
- HeapSnapshotGenerator* generator_;
+ V8HeapExplorer* generator_;
HeapObject* parent_obj_;
HeapEntry* parent_;
HeapObjectsSet* known_references_;
@@ -1933,7 +1796,7 @@
};
-void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
+void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
HeapEntry* entry = GetEntry(obj);
if (entry == NULL) return; // No interest in this object.
@@ -1977,8 +1840,8 @@
}
-void HeapSnapshotGenerator::ExtractClosureReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->IsJSFunction()) {
HandleScope hs;
JSFunction* func = JSFunction::cast(js_obj);
@@ -2000,8 +1863,8 @@
}
-void HeapSnapshotGenerator::ExtractPropertyReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->HasFastProperties()) {
DescriptorArray* descs = js_obj->map()->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
@@ -2042,8 +1905,8 @@
}
-void HeapSnapshotGenerator::ExtractElementReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->HasFastElements()) {
FixedArray* elements = FixedArray::cast(js_obj->elements());
int length = js_obj->IsJSArray() ?
@@ -2069,8 +1932,8 @@
}
-void HeapSnapshotGenerator::ExtractInternalReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
+ HeapEntry* entry) {
int length = js_obj->GetInternalFieldCount();
for (int i = 0; i < length; ++i) {
Object* o = js_obj->GetInternalField(i);
@@ -2079,10 +1942,55 @@
}
-void HeapSnapshotGenerator::SetClosureReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- String* reference_name,
- Object* child_obj) {
+HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
+ if (!obj->IsHeapObject()) return NULL;
+ return filler_->FindOrAddEntry(obj);
+}
+
+
+class RootsReferencesExtractor : public ObjectVisitor {
+ public:
+ explicit RootsReferencesExtractor(V8HeapExplorer* explorer)
+ : explorer_(explorer) {
+ }
+ void VisitPointers(Object** start, Object** end) {
+ for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
+ }
+ private:
+ V8HeapExplorer* explorer_;
+};
+
+
+bool V8HeapExplorer::IterateAndExtractReferences(
+ SnapshotFillerInterface* filler) {
+ filler_ = filler;
+ HeapIterator iterator(HeapIterator::kFilterUnreachable);
+ bool interrupted = false;
+ // Heap iteration with filtering must be finished in any case.
+ for (HeapObject* obj = iterator.next();
+ obj != NULL;
+ obj = iterator.next(), progress_->ProgressStep()) {
+ if (!interrupted) {
+ ExtractReferences(obj);
+ if (!progress_->ProgressReport(false)) interrupted = true;
+ }
+ }
+ if (interrupted) {
+ filler_ = NULL;
+ return false;
+ }
+ SetRootGcRootsReference();
+ RootsReferencesExtractor extractor(this);
+ HEAP->IterateRoots(&extractor, VISIT_ALL);
+ filler_ = NULL;
+ return progress_->ProgressReport(false);
+}
+
+
+void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ String* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
@@ -2096,10 +2004,10 @@
}
-void HeapSnapshotGenerator::SetElementReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetIndexedReference(HeapGraphEdge::kElement,
@@ -2113,10 +2021,10 @@
}
-void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- const char* reference_name,
- Object* child_obj) {
+void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ const char* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2130,10 +2038,10 @@
}
-void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2147,10 +2055,10 @@
}
-void HeapSnapshotGenerator::SetHiddenReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetIndexedReference(HeapGraphEdge::kHidden,
@@ -2163,10 +2071,10 @@
}
-void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- String* reference_name,
- Object* child_obj) {
+void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ String* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
HeapGraphEdge::Type type = reference_name->length() > 0 ?
@@ -2182,7 +2090,7 @@
}
-void HeapSnapshotGenerator::SetPropertyShortcutReference(
+void V8HeapExplorer::SetPropertyShortcutReference(
HeapObject* parent_obj,
HeapEntry* parent_entry,
String* reference_name,
@@ -2199,52 +2107,221 @@
}
-void HeapSnapshotGenerator::SetRootGcRootsReference() {
- filler_->SetRootGcRootsReference();
+void V8HeapExplorer::SetRootGcRootsReference() {
+ filler_->SetIndexedAutoIndexReference(
+ HeapGraphEdge::kElement,
+ kInternalRootObject, snapshot_->root(),
+ kGcRootsObject, snapshot_->gc_roots());
}
-void HeapSnapshotGenerator::SetRootShortcutReference(Object* child_obj) {
+void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
ASSERT(child_entry != NULL);
- filler_->SetRootShortcutReference(child_obj, child_entry);
+ filler_->SetNamedAutoIndexReference(
+ HeapGraphEdge::kShortcut,
+ kInternalRootObject, snapshot_->root(),
+ child_obj, child_entry);
}
-void HeapSnapshotGenerator::SetGcRootsReference(Object* child_obj) {
+void V8HeapExplorer::SetGcRootsReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
- filler_->SetStrongRootReference(child_obj, child_entry);
+ filler_->SetIndexedAutoIndexReference(
+ HeapGraphEdge::kElement,
+ kGcRootsObject, snapshot_->gc_roots(),
+ child_obj, child_entry);
}
}
+HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
+ v8::ActivityControl* control)
+ : snapshot_(snapshot),
+ control_(control),
+ v8_heap_explorer_(snapshot_, this) {
+}
+
+
+class SnapshotCounter : public SnapshotFillerInterface {
+ public:
+ SnapshotCounter(HeapEntriesAllocator* allocator, HeapEntriesMap* entries)
+ : allocator_(allocator), entries_(entries) { }
+ HeapEntry* AddEntry(HeapThing ptr) {
+ entries_->Pair(ptr, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
+ return HeapEntriesMap::kHeapEntryPlaceholder;
+ }
+ HeapEntry* FindOrAddEntry(HeapThing ptr) {
+ HeapEntry* entry = entries_->Map(ptr);
+ return entry != NULL ? entry : AddEntry(ptr);
+ }
+ void SetIndexedReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ int,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetNamedReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ const char*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetNamedAutoIndexReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ private:
+ HeapEntriesAllocator* allocator_;
+ HeapEntriesMap* entries_;
+};
+
+
+class SnapshotFiller : public SnapshotFillerInterface {
+ public:
+ explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
+ : snapshot_(snapshot),
+ collection_(snapshot->collection()),
+ entries_(entries) { }
+ HeapEntry* AddEntry(HeapThing ptr) {
+ UNREACHABLE();
+ return NULL;
+ }
+ HeapEntry* FindOrAddEntry(HeapThing ptr) {
+ HeapEntry* entry = entries_->Map(ptr);
+ return entry != NULL ? entry : AddEntry(ptr);
+ }
+ void SetIndexedReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ int index,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetIndexedReference(
+ type, child_index, index, child_entry, retainer_index);
+ }
+ void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetIndexedReference(
+ type, child_index, child_index + 1, child_entry, retainer_index);
+ }
+ void SetNamedReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ const char* reference_name,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetNamedReference(
+ type, child_index, reference_name, child_entry, retainer_index);
+ }
+ void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetNamedReference(type,
+ child_index,
+ collection_->GetName(child_index + 1),
+ child_entry,
+ retainer_index);
+ }
+ private:
+ HeapSnapshot* snapshot_;
+ HeapSnapshotsCollection* collection_;
+ HeapEntriesMap* entries_;
+};
+
+
+bool HeapSnapshotGenerator::GenerateSnapshot() {
+ AssertNoAllocation no_alloc;
+
+ SetProgressTotal(4); // 2 passes + dominators + sizes.
+
+ // Pass 1. Iterate heap contents to count entries and references.
+ if (!CountEntriesAndReferences()) return false;
+
+ // Allocate and fill entries in the snapshot, allocate references.
+ snapshot_->AllocateEntries(entries_.entries_count(),
+ entries_.total_children_count(),
+ entries_.total_retainers_count());
+ entries_.AllocateEntries();
+
+ // Pass 2. Fill references.
+ if (!FillReferences()) return false;
+
+ if (!SetEntriesDominators()) return false;
+ if (!ApproximateRetainedSizes()) return false;
+
+ progress_counter_ = progress_total_;
+ if (!ProgressReport(true)) return false;
+ return true;
+}
+
+
+void HeapSnapshotGenerator::ProgressStep() {
+ ++progress_counter_;
+}
+
+
+bool HeapSnapshotGenerator::ProgressReport(bool force) {
+ const int kProgressReportGranularity = 10000;
+ if (control_ != NULL
+ && (force || progress_counter_ % kProgressReportGranularity == 0)) {
+ return
+ control_->ReportProgressValue(progress_counter_, progress_total_) ==
+ v8::ActivityControl::kContinue;
+ }
+ return true;
+}
+
+
void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
if (control_ == NULL) return;
-
- HeapIterator iterator(HeapIterator::kFilterUnreachable);
- int objects_count = 0;
- for (HeapObject* obj = iterator.next();
- obj != NULL;
- obj = iterator.next(), ++objects_count) {}
- progress_total_ = objects_count * iterations_count;
+ progress_total_ = v8_heap_explorer_.EstimateObjectsCount() * iterations_count;
progress_counter_ = 0;
}
bool HeapSnapshotGenerator::CountEntriesAndReferences() {
- SnapshotCounter counter(&entries_);
- filler_ = &counter;
- filler_->AddEntry(HeapSnapshot::kInternalRootObject);
- filler_->AddEntry(HeapSnapshot::kGcRootsObject);
- return IterateAndExtractReferences();
+ SnapshotCounter counter(&v8_heap_explorer_, &entries_);
+ v8_heap_explorer_.AddRootEntries(&counter);
+ return v8_heap_explorer_.IterateAndExtractReferences(&counter);
}
bool HeapSnapshotGenerator::FillReferences() {
SnapshotFiller filler(snapshot_, &entries_);
- filler_ = &filler;
- return IterateAndExtractReferences();
+ return v8_heap_explorer_.IterateAndExtractReferences(&filler);
}
@@ -2289,7 +2366,7 @@
// The algorithm is based on the article:
// K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
-// Softw. Pract. Exper. 4 (2001), pp. 1–10.
+// Softw. Pract. Exper. 4 (2001), pp. 1-10.
bool HeapSnapshotGenerator::BuildDominatorTree(
const Vector<HeapEntry*>& entries,
Vector<HeapEntry*>* dominators) {
@@ -2330,7 +2407,7 @@
int remaining = entries_length - changed;
if (remaining < 0) remaining = 0;
progress_counter_ = base_progress_counter + remaining;
- if (!ReportProgress(true)) return false;
+ if (!ProgressReport(true)) return false;
}
return true;
}
@@ -2360,7 +2437,7 @@
}
for (int i = 0;
i < snapshot_->entries()->length();
- ++i, IncProgressCounter()) {
+ ++i, ProgressStep()) {
HeapEntry* entry = snapshot_->entries()->at(i);
int entry_size = entry->self_size();
for (HeapEntry* dominator = entry->dominator();
@@ -2368,32 +2445,12 @@
entry = dominator, dominator = entry->dominator()) {
dominator->add_retained_size(entry_size);
}
- if (!ReportProgress()) return false;
+ if (!ProgressReport()) return false;
}
return true;
}
-bool HeapSnapshotGenerator::IterateAndExtractReferences() {
- HeapIterator iterator(HeapIterator::kFilterUnreachable);
- bool interrupted = false;
- // Heap iteration with filtering must be finished in any case.
- for (HeapObject* obj = iterator.next();
- obj != NULL;
- obj = iterator.next(), IncProgressCounter()) {
- if (!interrupted) {
- ExtractReferences(obj);
- if (!ReportProgress()) interrupted = true;
- }
- }
- if (interrupted) return false;
- SetRootGcRootsReference();
- RootsReferencesExtractor extractor(this);
- HEAP->IterateRoots(&extractor, VISIT_ALL);
- return ReportProgress();
-}
-
-
void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
raw_additions_root_ =
NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698