Commit 054bdf7f authored by yurys@chromium.org's avatar yurys@chromium.org

Remove HeapSnapshotsCollection class

The class added unecessary level of indirection to the heap profiler implementation. I merged some of its implementation into HeapProfiler and deleted the rest. This refactoring is also a prerequisite for keeping HeapObjectsMap alive even when all snapshots are deleted.

BUG=None
LOG=N
R=alph@chromium.org, mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18221 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0fd81694
...@@ -28,28 +28,41 @@ ...@@ -28,28 +28,41 @@
#include "v8.h" #include "v8.h"
#include "heap-profiler.h" #include "heap-profiler.h"
#include "allocation-tracker.h"
#include "heap-snapshot-generator-inl.h" #include "heap-snapshot-generator-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
HeapProfiler::HeapProfiler(Heap* heap) HeapProfiler::HeapProfiler(Heap* heap)
: snapshots_(new HeapSnapshotsCollection(heap)), : ids_(new HeapObjectsMap(heap)),
names_(new StringsStorage(heap)),
next_snapshot_uid_(1), next_snapshot_uid_(1),
is_tracking_allocations_(false),
is_tracking_object_moves_(false) { is_tracking_object_moves_(false) {
} }
static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
delete *snapshot_ptr;
}
HeapProfiler::~HeapProfiler() { HeapProfiler::~HeapProfiler() {
delete snapshots_; snapshots_.Iterate(DeleteHeapSnapshot);
snapshots_.Clear();
} }
void HeapProfiler::DeleteAllSnapshots() { void HeapProfiler::DeleteAllSnapshots() {
Heap* the_heap = heap(); snapshots_.Iterate(DeleteHeapSnapshot);
delete snapshots_; snapshots_.Clear();
snapshots_ = new HeapSnapshotsCollection(the_heap); names_.Reset(new StringsStorage(heap()));
}
void HeapProfiler::RemoveSnapshot(HeapSnapshot* snapshot) {
snapshots_.RemoveElement(snapshot);
} }
...@@ -76,15 +89,17 @@ HeapSnapshot* HeapProfiler::TakeSnapshot( ...@@ -76,15 +89,17 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(
const char* name, const char* name,
v8::ActivityControl* control, v8::ActivityControl* control,
v8::HeapProfiler::ObjectNameResolver* resolver) { v8::HeapProfiler::ObjectNameResolver* resolver) {
HeapSnapshot* result = snapshots_->NewSnapshot(name, next_snapshot_uid_++); HeapSnapshot* result = new HeapSnapshot(this, name, next_snapshot_uid_++);
{ {
HeapSnapshotGenerator generator(result, control, resolver, heap()); HeapSnapshotGenerator generator(result, control, resolver, heap());
if (!generator.GenerateSnapshot()) { if (!generator.GenerateSnapshot()) {
delete result; delete result;
result = NULL; result = NULL;
} else {
snapshots_.Add(result);
} }
} }
snapshots_->SnapshotGenerationFinished(result); ids_->RemoveDeadEntries();
is_tracking_object_moves_ = true; is_tracking_object_moves_ = true;
return result; return result;
} }
...@@ -94,69 +109,79 @@ HeapSnapshot* HeapProfiler::TakeSnapshot( ...@@ -94,69 +109,79 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(
String* name, String* name,
v8::ActivityControl* control, v8::ActivityControl* control,
v8::HeapProfiler::ObjectNameResolver* resolver) { v8::HeapProfiler::ObjectNameResolver* resolver) {
return TakeSnapshot(snapshots_->names()->GetName(name), control, resolver); return TakeSnapshot(names_->GetName(name), control, resolver);
} }
void HeapProfiler::StartHeapObjectsTracking(bool track_allocations) { void HeapProfiler::StartHeapObjectsTracking(bool track_allocations) {
snapshots_->StartHeapObjectsTracking(track_allocations); ids_->UpdateHeapObjectsMap();
is_tracking_object_moves_ = true; is_tracking_object_moves_ = true;
ASSERT(!is_tracking_allocations_); ASSERT(!is_tracking_allocations());
if (track_allocations) { if (track_allocations) {
allocation_tracker_.Reset(new AllocationTracker(*ids_, *names_));
heap()->DisableInlineAllocation(); heap()->DisableInlineAllocation();
is_tracking_allocations_ = true;
} }
} }
SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) { SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) {
return snapshots_->PushHeapObjectsStats(stream); return ids_->PushHeapObjectsStats(stream);
} }
void HeapProfiler::StopHeapObjectsTracking() { void HeapProfiler::StopHeapObjectsTracking() {
snapshots_->StopHeapObjectsTracking(); ids_->StopHeapObjectsTracking();
if (is_tracking_allocations_) { if (is_tracking_allocations()) {
allocation_tracker_.Reset(NULL);
heap()->EnableInlineAllocation(); heap()->EnableInlineAllocation();
is_tracking_allocations_ = false;
} }
} }
size_t HeapProfiler::GetMemorySizeUsedByProfiler() { size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
return snapshots_->GetUsedMemorySize(); size_t size = sizeof(*this);
size += names_->GetUsedMemorySize();
size += ids_->GetUsedMemorySize();
size += GetMemoryUsedByList(snapshots_);
for (int i = 0; i < snapshots_.length(); ++i) {
size += snapshots_[i]->RawSnapshotSize();
}
return size;
} }
int HeapProfiler::GetSnapshotsCount() { int HeapProfiler::GetSnapshotsCount() {
return snapshots_->snapshots()->length(); return snapshots_.length();
} }
HeapSnapshot* HeapProfiler::GetSnapshot(int index) { HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
return snapshots_->snapshots()->at(index); return snapshots_.at(index);
} }
SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) { SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) {
if (!obj->IsHeapObject()) if (!obj->IsHeapObject())
return v8::HeapProfiler::kUnknownObjectId; return v8::HeapProfiler::kUnknownObjectId;
return snapshots_->FindObjectId(HeapObject::cast(*obj)->address()); return ids_->FindEntry(HeapObject::cast(*obj)->address());
} }
void HeapProfiler::ObjectMoveEvent(Address from, Address to, int size) { void HeapProfiler::ObjectMoveEvent(Address from, Address to, int size) {
snapshots_->ObjectMoveEvent(from, to, size); ids_->MoveObject(from, to, size);
} }
void HeapProfiler::AllocationEvent(Address addr, int size) { void HeapProfiler::AllocationEvent(Address addr, int size) {
snapshots_->AllocationEvent(addr, size); DisallowHeapAllocation no_allocation;
if (!allocation_tracker_.is_empty()) {
allocation_tracker_->AllocationEvent(addr, size);
}
} }
void HeapProfiler::UpdateObjectSizeEvent(Address addr, int size) { void HeapProfiler::UpdateObjectSizeEvent(Address addr, int size) {
snapshots_->UpdateObjectSizeEvent(addr, size); ids_->UpdateObjectSize(addr, size);
} }
...@@ -167,4 +192,24 @@ void HeapProfiler::SetRetainedObjectInfo(UniqueId id, ...@@ -167,4 +192,24 @@ void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
} }
Handle<HeapObject> HeapProfiler::FindHeapObjectById(SnapshotObjectId id) {
heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"HeapProfiler::FindHeapObjectById");
DisallowHeapAllocation no_allocation;
HeapObject* object = NULL;
HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
// Make sure that object with the given id is still reachable.
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
if (ids_->FindEntry(obj->address()) == id) {
ASSERT(object == NULL);
object = obj;
// Can't break -- kFilterUnreachable requires full heap traversal.
}
}
return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>();
}
} } // namespace v8::internal } } // namespace v8::internal
...@@ -30,12 +30,12 @@ ...@@ -30,12 +30,12 @@
#include "heap-snapshot-generator-inl.h" #include "heap-snapshot-generator-inl.h"
#include "isolate.h" #include "isolate.h"
#include "smart-pointers.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class HeapSnapshot; class HeapSnapshot;
class HeapSnapshotsCollection;
class HeapProfiler { class HeapProfiler {
public: public:
...@@ -55,12 +55,16 @@ class HeapProfiler { ...@@ -55,12 +55,16 @@ class HeapProfiler {
void StartHeapObjectsTracking(bool track_allocations); void StartHeapObjectsTracking(bool track_allocations);
void StopHeapObjectsTracking(); void StopHeapObjectsTracking();
AllocationTracker* allocation_tracker() { return *allocation_tracker_; }
HeapObjectsMap* heap_object_map() { return *ids_; }
StringsStorage* names() { return *names_; }
SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
int GetSnapshotsCount(); int GetSnapshotsCount();
HeapSnapshot* GetSnapshot(int index); HeapSnapshot* GetSnapshot(int index);
SnapshotObjectId GetSnapshotObjectId(Handle<Object> obj); SnapshotObjectId GetSnapshotObjectId(Handle<Object> obj);
void DeleteAllSnapshots(); void DeleteAllSnapshots();
void RemoveSnapshot(HeapSnapshot* snapshot);
void ObjectMoveEvent(Address from, Address to, int size); void ObjectMoveEvent(Address from, Address to, int size);
...@@ -76,19 +80,20 @@ class HeapProfiler { ...@@ -76,19 +80,20 @@ class HeapProfiler {
void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info); void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
bool is_tracking_object_moves() const { return is_tracking_object_moves_; } bool is_tracking_object_moves() const { return is_tracking_object_moves_; }
bool is_tracking_allocations() const { return is_tracking_allocations_; } bool is_tracking_allocations() { return !allocation_tracker_.is_empty(); }
int FindUntrackedObjects() { Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id);
return snapshots_->FindUntrackedObjects();
}
private: private:
Heap* heap() const { return snapshots_->heap(); } Heap* heap() const { return ids_->heap(); }
HeapSnapshotsCollection* snapshots_; // Mapping from HeapObject addresses to objects' uids.
SmartPointer<HeapObjectsMap> ids_;
List<HeapSnapshot*> snapshots_;
SmartPointer<StringsStorage> names_;
unsigned next_snapshot_uid_; unsigned next_snapshot_uid_;
List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_;
bool is_tracking_allocations_; SmartPointer<AllocationTracker> allocation_tracker_;
bool is_tracking_object_moves_; bool is_tracking_object_moves_;
}; };
......
...@@ -100,7 +100,7 @@ void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type, ...@@ -100,7 +100,7 @@ void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type,
Handle<HeapObject> HeapEntry::GetHeapObject() { Handle<HeapObject> HeapEntry::GetHeapObject() {
return snapshot_->collection()->FindHeapObjectById(id()); return snapshot_->profiler()->FindHeapObjectById(id());
} }
...@@ -202,10 +202,10 @@ template <> struct SnapshotSizeConstants<8> { ...@@ -202,10 +202,10 @@ template <> struct SnapshotSizeConstants<8> {
} // namespace } // namespace
HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, HeapSnapshot::HeapSnapshot(HeapProfiler* profiler,
const char* title, const char* title,
unsigned uid) unsigned uid)
: collection_(collection), : profiler_(profiler),
title_(title), title_(title),
uid_(uid), uid_(uid),
root_index_(HeapEntry::kNoEntry), root_index_(HeapEntry::kNoEntry),
...@@ -225,13 +225,13 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, ...@@ -225,13 +225,13 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
void HeapSnapshot::Delete() { void HeapSnapshot::Delete() {
collection_->RemoveSnapshot(this); profiler_->RemoveSnapshot(this);
delete this; delete this;
} }
void HeapSnapshot::RememberLastJSObjectId() { void HeapSnapshot::RememberLastJSObjectId() {
max_snapshot_js_object_id_ = collection_->last_assigned_id(); max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id();
} }
...@@ -346,12 +346,6 @@ void HeapSnapshot::Print(int max_depth) { ...@@ -346,12 +346,6 @@ void HeapSnapshot::Print(int max_depth) {
} }
template<typename T, class P>
static size_t GetMemoryUsedByList(const List<T, P>& list) {
return list.length() * sizeof(T) + sizeof(list);
}
size_t HeapSnapshot::RawSnapshotSize() const { size_t HeapSnapshot::RawSnapshotSize() const {
return return
sizeof(*this) + sizeof(*this) +
...@@ -394,11 +388,6 @@ HeapObjectsMap::HeapObjectsMap(Heap* heap) ...@@ -394,11 +388,6 @@ HeapObjectsMap::HeapObjectsMap(Heap* heap)
} }
void HeapObjectsMap::SnapshotGenerationFinished() {
RemoveDeadEntries();
}
void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) {
ASSERT(to != NULL); ASSERT(to != NULL);
ASSERT(from != NULL); ASSERT(from != NULL);
...@@ -502,7 +491,7 @@ void HeapObjectsMap::UpdateHeapObjectsMap() { ...@@ -502,7 +491,7 @@ void HeapObjectsMap::UpdateHeapObjectsMap() {
entries_map_.occupancy()); entries_map_.occupancy());
} }
heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask, heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"HeapSnapshotsCollection::UpdateHeapObjectsMap"); "HeapObjectsMap::UpdateHeapObjectsMap");
HeapIterator iterator(heap_); HeapIterator iterator(heap_);
for (HeapObject* obj = iterator.next(); for (HeapObject* obj = iterator.next();
obj != NULL; obj != NULL;
...@@ -710,13 +699,12 @@ void HeapObjectsMap::RemoveDeadEntries() { ...@@ -710,13 +699,12 @@ void HeapObjectsMap::RemoveDeadEntries() {
} }
SnapshotObjectId HeapObjectsMap::GenerateId(Heap* heap, SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
v8::RetainedObjectInfo* info) {
SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash()); SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash());
const char* label = info->GetLabel(); const char* label = info->GetLabel();
id ^= StringHasher::HashSequentialString(label, id ^= StringHasher::HashSequentialString(label,
static_cast<int>(strlen(label)), static_cast<int>(strlen(label)),
heap->HashSeed()); heap_->HashSeed());
intptr_t element_count = info->GetElementCount(); intptr_t element_count = info->GetElementCount();
if (element_count != -1) if (element_count != -1)
id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count), id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count),
...@@ -734,104 +722,6 @@ size_t HeapObjectsMap::GetUsedMemorySize() const { ...@@ -734,104 +722,6 @@ size_t HeapObjectsMap::GetUsedMemorySize() const {
} }
HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap)
: names_(heap),
ids_(heap),
allocation_tracker_(NULL) {
}
static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
delete *snapshot_ptr;
}
HeapSnapshotsCollection::~HeapSnapshotsCollection() {
delete allocation_tracker_;
snapshots_.Iterate(DeleteHeapSnapshot);
}
void HeapSnapshotsCollection::StartHeapObjectsTracking(bool track_allocations) {
ids_.UpdateHeapObjectsMap();
ASSERT(allocation_tracker_ == NULL);
if (track_allocations) {
allocation_tracker_ = new AllocationTracker(&ids_, names());
}
}
void HeapSnapshotsCollection::StopHeapObjectsTracking() {
ids_.StopHeapObjectsTracking();
if (allocation_tracker_ != NULL) {
delete allocation_tracker_;
allocation_tracker_ = NULL;
}
}
HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name,
unsigned uid) {
return new HeapSnapshot(this, name, uid);
}
void HeapSnapshotsCollection::SnapshotGenerationFinished(
HeapSnapshot* snapshot) {
ids_.SnapshotGenerationFinished();
if (snapshot != NULL) {
snapshots_.Add(snapshot);
}
}
void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
snapshots_.RemoveElement(snapshot);
}
Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
SnapshotObjectId id) {
// First perform a full GC in order to avoid dead objects.
heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"HeapSnapshotsCollection::FindHeapObjectById");
DisallowHeapAllocation no_allocation;
HeapObject* object = NULL;
HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
// Make sure that object with the given id is still reachable.
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
if (ids_.FindEntry(obj->address()) == id) {
ASSERT(object == NULL);
object = obj;
// Can't break -- kFilterUnreachable requires full heap traversal.
}
}
return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>();
}
void HeapSnapshotsCollection::AllocationEvent(Address addr, int size) {
DisallowHeapAllocation no_allocation;
if (allocation_tracker_ != NULL) {
allocation_tracker_->AllocationEvent(addr, size);
}
}
size_t HeapSnapshotsCollection::GetUsedMemorySize() const {
size_t size = sizeof(*this);
size += names_.GetUsedMemorySize();
size += ids_.GetUsedMemorySize();
size += GetMemoryUsedByList(snapshots_);
for (int i = 0; i < snapshots_.length(); ++i) {
size += snapshots_[i]->RawSnapshotSize();
}
return size;
}
HeapEntriesMap::HeapEntriesMap() HeapEntriesMap::HeapEntriesMap()
: entries_(HeapThingsMatch) { : entries_(HeapThingsMatch) {
} }
...@@ -912,9 +802,10 @@ V8HeapExplorer::V8HeapExplorer( ...@@ -912,9 +802,10 @@ V8HeapExplorer::V8HeapExplorer(
HeapSnapshot* snapshot, HeapSnapshot* snapshot,
SnapshottingProgressReportingInterface* progress, SnapshottingProgressReportingInterface* progress,
v8::HeapProfiler::ObjectNameResolver* resolver) v8::HeapProfiler::ObjectNameResolver* resolver)
: heap_(snapshot->collection()->heap()), : heap_(snapshot->profiler()->heap_object_map()->heap()),
snapshot_(snapshot), snapshot_(snapshot),
collection_(snapshot_->collection()), names_(snapshot_->profiler()->names()),
heap_object_map_(snapshot_->profiler()->heap_object_map()),
progress_(progress), progress_(progress),
filler_(NULL), filler_(NULL),
global_object_name_resolver_(resolver) { global_object_name_resolver_(resolver) {
...@@ -944,20 +835,20 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { ...@@ -944,20 +835,20 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
JSFunction* func = JSFunction::cast(object); JSFunction* func = JSFunction::cast(object);
SharedFunctionInfo* shared = func->shared(); SharedFunctionInfo* shared = func->shared();
const char* name = shared->bound() ? "native_bind" : const char* name = shared->bound() ? "native_bind" :
collection_->names()->GetName(String::cast(shared->name())); names_->GetName(String::cast(shared->name()));
return AddEntry(object, HeapEntry::kClosure, name); return AddEntry(object, HeapEntry::kClosure, name);
} else if (object->IsJSRegExp()) { } else if (object->IsJSRegExp()) {
JSRegExp* re = JSRegExp::cast(object); JSRegExp* re = JSRegExp::cast(object);
return AddEntry(object, return AddEntry(object,
HeapEntry::kRegExp, HeapEntry::kRegExp,
collection_->names()->GetName(re->Pattern())); names_->GetName(re->Pattern()));
} else if (object->IsJSObject()) { } else if (object->IsJSObject()) {
const char* name = collection_->names()->GetName( const char* name = names_->GetName(
GetConstructorName(JSObject::cast(object))); GetConstructorName(JSObject::cast(object)));
if (object->IsJSGlobalObject()) { if (object->IsJSGlobalObject()) {
const char* tag = objects_tags_.GetTag(object); const char* tag = objects_tags_.GetTag(object);
if (tag != NULL) { if (tag != NULL) {
name = collection_->names()->GetFormatted("%s / %s", name, tag); name = names_->GetFormatted("%s / %s", name, tag);
} }
} }
return AddEntry(object, HeapEntry::kObject, name); return AddEntry(object, HeapEntry::kObject, name);
...@@ -973,20 +864,20 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { ...@@ -973,20 +864,20 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
"(sliced string)"); "(sliced string)");
return AddEntry(object, return AddEntry(object,
HeapEntry::kString, HeapEntry::kString,
collection_->names()->GetName(String::cast(object))); names_->GetName(String::cast(object)));
} else if (object->IsCode()) { } else if (object->IsCode()) {
return AddEntry(object, HeapEntry::kCode, ""); return AddEntry(object, HeapEntry::kCode, "");
} else if (object->IsSharedFunctionInfo()) { } else if (object->IsSharedFunctionInfo()) {
String* name = String::cast(SharedFunctionInfo::cast(object)->name()); String* name = String::cast(SharedFunctionInfo::cast(object)->name());
return AddEntry(object, return AddEntry(object,
HeapEntry::kCode, HeapEntry::kCode,
collection_->names()->GetName(name)); names_->GetName(name));
} else if (object->IsScript()) { } else if (object->IsScript()) {
Object* name = Script::cast(object)->name(); Object* name = Script::cast(object)->name();
return AddEntry(object, return AddEntry(object,
HeapEntry::kCode, HeapEntry::kCode,
name->IsString() name->IsString()
? collection_->names()->GetName(String::cast(name)) ? names_->GetName(String::cast(name))
: ""); : "");
} else if (object->IsNativeContext()) { } else if (object->IsNativeContext()) {
return AddEntry(object, HeapEntry::kHidden, "system / NativeContext"); return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
...@@ -1009,7 +900,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, ...@@ -1009,7 +900,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
const char* name) { const char* name) {
int object_size = object->Size(); int object_size = object->Size();
SnapshotObjectId object_id = SnapshotObjectId object_id =
collection_->GetObjectId(object->address(), object_size); heap_object_map_->FindOrAddEntry(object->address(), object_size);
return snapshot_->AddEntry(type, name, object_id, object_size); return snapshot_->AddEntry(type, name, object_id, object_size);
} }
...@@ -1356,14 +1247,13 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) { ...@@ -1356,14 +1247,13 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
void V8HeapExplorer::ExtractSharedFunctionInfoReferences( void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
int entry, SharedFunctionInfo* shared) { int entry, SharedFunctionInfo* shared) {
HeapObject* obj = shared; HeapObject* obj = shared;
StringsStorage* names = collection_->names();
String* shared_name = shared->DebugName(); String* shared_name = shared->DebugName();
const char* name = NULL; const char* name = NULL;
if (shared_name != *heap_->isolate()->factory()->empty_string()) { if (shared_name != *heap_->isolate()->factory()->empty_string()) {
name = names->GetName(shared_name); name = names_->GetName(shared_name);
TagObject(shared->code(), names->GetFormatted("(code for %s)", name)); TagObject(shared->code(), names_->GetFormatted("(code for %s)", name));
} else { } else {
TagObject(shared->code(), names->GetFormatted("(%s code)", TagObject(shared->code(), names_->GetFormatted("(%s code)",
Code::Kind2String(shared->code()->kind()))); Code::Kind2String(shared->code()->kind())));
} }
...@@ -1384,7 +1274,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences( ...@@ -1384,7 +1274,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
"script", shared->script(), "script", shared->script(),
SharedFunctionInfo::kScriptOffset); SharedFunctionInfo::kScriptOffset);
const char* construct_stub_name = name ? const char* construct_stub_name = name ?
names->GetFormatted("(construct stub code for %s)", name) : names_->GetFormatted("(construct stub code for %s)", name) :
"(construct stub code)"; "(construct stub code)";
TagObject(shared->construct_stub(), construct_stub_name); TagObject(shared->construct_stub(), construct_stub_name);
SetInternalReference(obj, entry, SetInternalReference(obj, entry,
...@@ -1452,14 +1342,13 @@ void V8HeapExplorer::ExtractCodeCacheReferences( ...@@ -1452,14 +1342,13 @@ void V8HeapExplorer::ExtractCodeCacheReferences(
void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) { void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) {
TagObject(code, collection_->names()->GetFormatted("(%s code)", TagObject(code, names_->GetFormatted("(%s code)", external_name));
external_name));
} }
void V8HeapExplorer::TagCodeObject(Code* code) { void V8HeapExplorer::TagCodeObject(Code* code) {
if (code->kind() == Code::STUB) { if (code->kind() == Code::STUB) {
TagObject(code, collection_->names()->GetFormatted( TagObject(code, names_->GetFormatted(
"(%s code)", CodeStub::MajorName( "(%s code)", CodeStub::MajorName(
static_cast<CodeStub::Major>(code->major_key()), true))); static_cast<CodeStub::Major>(code->major_key()), true)));
} }
...@@ -1537,7 +1426,7 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { ...@@ -1537,7 +1426,7 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
bindings->get(JSFunction::kBoundFunctionIndex)); bindings->get(JSFunction::kBoundFunctionIndex));
for (int i = JSFunction::kBoundArgumentsStartIndex; for (int i = JSFunction::kBoundArgumentsStartIndex;
i < bindings->length(); i++) { i < bindings->length(); i++) {
const char* reference_name = collection_->names()->GetFormatted( const char* reference_name = names_->GetFormatted(
"bound_argument_%d", "bound_argument_%d",
i - JSFunction::kBoundArgumentsStartIndex); i - JSFunction::kBoundArgumentsStartIndex);
SetNativeBindReference(js_obj, entry, reference_name, SetNativeBindReference(js_obj, entry, reference_name,
...@@ -1844,7 +1733,7 @@ void V8HeapExplorer::SetContextReference(HeapObject* parent_obj, ...@@ -1844,7 +1733,7 @@ void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
if (child_entry != NULL) { if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kContextVariable, filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
parent_entry, parent_entry,
collection_->names()->GetName(reference_name), names_->GetName(reference_name),
child_entry); child_entry);
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
} }
...@@ -1910,7 +1799,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, ...@@ -1910,7 +1799,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
filler_->SetNamedReference(HeapGraphEdge::kInternal, filler_->SetNamedReference(HeapGraphEdge::kInternal,
parent_entry, parent_entry,
collection_->names()->GetName(index), names_->GetName(index),
child_entry); child_entry);
} }
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
...@@ -1963,11 +1852,11 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, ...@@ -1963,11 +1852,11 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
reference_name->IsSymbol() || String::cast(reference_name)->length() > 0 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0
? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
const char* name = name_format_string != NULL && reference_name->IsString() const char* name = name_format_string != NULL && reference_name->IsString()
? collection_->names()->GetFormatted( ? names_->GetFormatted(
name_format_string, name_format_string,
*String::cast(reference_name)->ToCString( *String::cast(reference_name)->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) : DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) :
collection_->names()->GetName(reference_name); names_->GetName(reference_name);
filler_->SetNamedReference(type, filler_->SetNamedReference(type,
parent_entry, parent_entry,
...@@ -2143,13 +2032,15 @@ class BasicHeapEntriesAllocator : public HeapEntriesAllocator { ...@@ -2143,13 +2032,15 @@ class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
HeapSnapshot* snapshot, HeapSnapshot* snapshot,
HeapEntry::Type entries_type) HeapEntry::Type entries_type)
: snapshot_(snapshot), : snapshot_(snapshot),
collection_(snapshot_->collection()), names_(snapshot_->profiler()->names()),
heap_object_map_(snapshot_->profiler()->heap_object_map()),
entries_type_(entries_type) { entries_type_(entries_type) {
} }
virtual HeapEntry* AllocateEntry(HeapThing ptr); virtual HeapEntry* AllocateEntry(HeapThing ptr);
private: private:
HeapSnapshot* snapshot_; HeapSnapshot* snapshot_;
HeapSnapshotsCollection* collection_; StringsStorage* names_;
HeapObjectsMap* heap_object_map_;
HeapEntry::Type entries_type_; HeapEntry::Type entries_type_;
}; };
...@@ -2159,13 +2050,13 @@ HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) { ...@@ -2159,13 +2050,13 @@ HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) {
intptr_t elements = info->GetElementCount(); intptr_t elements = info->GetElementCount();
intptr_t size = info->GetSizeInBytes(); intptr_t size = info->GetSizeInBytes();
const char* name = elements != -1 const char* name = elements != -1
? collection_->names()->GetFormatted( ? names_->GetFormatted(
"%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements) "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements)
: collection_->names()->GetCopy(info->GetLabel()); : names_->GetCopy(info->GetLabel());
return snapshot_->AddEntry( return snapshot_->AddEntry(
entries_type_, entries_type_,
name, name,
HeapObjectsMap::GenerateId(collection_->heap(), info), heap_object_map_->GenerateId(info),
size != -1 ? static_cast<int>(size) : 0); size != -1 ? static_cast<int>(size) : 0);
} }
...@@ -2173,9 +2064,9 @@ HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) { ...@@ -2173,9 +2064,9 @@ HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) {
NativeObjectsExplorer::NativeObjectsExplorer( NativeObjectsExplorer::NativeObjectsExplorer(
HeapSnapshot* snapshot, HeapSnapshot* snapshot,
SnapshottingProgressReportingInterface* progress) SnapshottingProgressReportingInterface* progress)
: isolate_(snapshot->collection()->heap()->isolate()), : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()),
snapshot_(snapshot), snapshot_(snapshot),
collection_(snapshot_->collection()), names_(snapshot_->profiler()->names()),
progress_(progress), progress_(progress),
embedder_queried_(false), embedder_queried_(false),
objects_by_info_(RetainedInfosMatch), objects_by_info_(RetainedInfosMatch),
...@@ -2337,7 +2228,7 @@ class NativeGroupRetainedObjectInfo : public v8::RetainedObjectInfo { ...@@ -2337,7 +2228,7 @@ class NativeGroupRetainedObjectInfo : public v8::RetainedObjectInfo {
NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
const char* label) { const char* label) {
const char* label_copy = collection_->names()->GetCopy(label); const char* label_copy = names_->GetCopy(label);
uint32_t hash = StringHasher::HashSequentialString( uint32_t hash = StringHasher::HashSequentialString(
label_copy, label_copy,
static_cast<int>(strlen(label_copy)), static_cast<int>(strlen(label_copy)),
...@@ -2415,7 +2306,7 @@ class SnapshotFiller : public SnapshotFillerInterface { ...@@ -2415,7 +2306,7 @@ class SnapshotFiller : public SnapshotFillerInterface {
public: public:
explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
: snapshot_(snapshot), : snapshot_(snapshot),
collection_(snapshot->collection()), names_(snapshot->profiler()->names()),
entries_(entries) { } entries_(entries) { }
HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
HeapEntry* entry = allocator->AllocateEntry(ptr); HeapEntry* entry = allocator->AllocateEntry(ptr);
...@@ -2458,13 +2349,13 @@ class SnapshotFiller : public SnapshotFillerInterface { ...@@ -2458,13 +2349,13 @@ class SnapshotFiller : public SnapshotFillerInterface {
int index = parent_entry->children_count() + 1; int index = parent_entry->children_count() + 1;
parent_entry->SetNamedReference( parent_entry->SetNamedReference(
type, type,
collection_->names()->GetName(index), names_->GetName(index),
child_entry); child_entry);
} }
private: private:
HeapSnapshot* snapshot_; HeapSnapshot* snapshot_;
HeapSnapshotsCollection* collection_; StringsStorage* names_;
HeapEntriesMap* entries_; HeapEntriesMap* entries_;
}; };
...@@ -2670,7 +2561,7 @@ const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5; ...@@ -2670,7 +2561,7 @@ const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5;
void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
if (AllocationTracker* allocation_tracker = if (AllocationTracker* allocation_tracker =
snapshot_->collection()->allocation_tracker()) { snapshot_->profiler()->allocation_tracker()) {
allocation_tracker->PrepareForSerialization(); allocation_tracker->PrepareForSerialization();
} }
ASSERT(writer_ == NULL); ASSERT(writer_ == NULL);
...@@ -2889,7 +2780,7 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() { ...@@ -2889,7 +2780,7 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() {
writer_->AddNumber(snapshot_->edges().length()); writer_->AddNumber(snapshot_->edges().length());
writer_->AddString(",\"trace_function_count\":"); writer_->AddString(",\"trace_function_count\":");
uint32_t count = 0; uint32_t count = 0;
AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
if (tracker) { if (tracker) {
count = tracker->id_to_function_info()->occupancy(); count = tracker->id_to_function_info()->occupancy();
} }
...@@ -2908,7 +2799,7 @@ static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { ...@@ -2908,7 +2799,7 @@ static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) {
void HeapSnapshotJSONSerializer::SerializeTraceTree() { void HeapSnapshotJSONSerializer::SerializeTraceTree() {
AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
if (!tracker) return; if (!tracker) return;
AllocationTraceTree* traces = tracker->trace_tree(); AllocationTraceTree* traces = tracker->trace_tree();
SerializeTraceNode(traces->root()); SerializeTraceNode(traces->root());
...@@ -2959,7 +2850,7 @@ static int SerializePosition(int position, const Vector<char>& buffer, ...@@ -2959,7 +2850,7 @@ static int SerializePosition(int position, const Vector<char>& buffer,
void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() {
AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
if (!tracker) return; if (!tracker) return;
// The buffer needs space for 6 unsigned ints, 6 commas, \n and \0 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0
const int kBufferSize = const int kBufferSize =
......
...@@ -154,21 +154,19 @@ class HeapEntry BASE_EMBEDDED { ...@@ -154,21 +154,19 @@ class HeapEntry BASE_EMBEDDED {
}; };
class HeapSnapshotsCollection;
// HeapSnapshot represents a single heap snapshot. It is stored in // HeapSnapshot represents a single heap snapshot. It is stored in
// HeapSnapshotsCollection, which is also a factory for // HeapProfiler, which is also a factory for
// HeapSnapshots. All HeapSnapshots share strings copied from JS heap // HeapSnapshots. All HeapSnapshots share strings copied from JS heap
// to be able to return them even if they were collected. // to be able to return them even if they were collected.
// HeapSnapshotGenerator fills in a HeapSnapshot. // HeapSnapshotGenerator fills in a HeapSnapshot.
class HeapSnapshot { class HeapSnapshot {
public: public:
HeapSnapshot(HeapSnapshotsCollection* collection, HeapSnapshot(HeapProfiler* profiler,
const char* title, const char* title,
unsigned uid); unsigned uid);
void Delete(); void Delete();
HeapSnapshotsCollection* collection() { return collection_; } HeapProfiler* profiler() { return profiler_; }
const char* title() { return title_; } const char* title() { return title_; }
unsigned uid() { return uid_; } unsigned uid() { return uid_; }
size_t RawSnapshotSize() const; size_t RawSnapshotSize() const;
...@@ -202,7 +200,7 @@ class HeapSnapshot { ...@@ -202,7 +200,7 @@ class HeapSnapshot {
void PrintEntriesSize(); void PrintEntriesSize();
private: private:
HeapSnapshotsCollection* collection_; HeapProfiler* profiler_;
const char* title_; const char* title_;
unsigned uid_; unsigned uid_;
int root_index_; int root_index_;
...@@ -227,7 +225,6 @@ class HeapObjectsMap { ...@@ -227,7 +225,6 @@ class HeapObjectsMap {
Heap* heap() const { return heap_; } Heap* heap() const { return heap_; }
void SnapshotGenerationFinished();
SnapshotObjectId FindEntry(Address addr); SnapshotObjectId FindEntry(Address addr);
SnapshotObjectId FindOrAddEntry(Address addr, SnapshotObjectId FindOrAddEntry(Address addr,
unsigned int size, unsigned int size,
...@@ -242,7 +239,7 @@ class HeapObjectsMap { ...@@ -242,7 +239,7 @@ class HeapObjectsMap {
SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
size_t GetUsedMemorySize() const; size_t GetUsedMemorySize() const;
static SnapshotObjectId GenerateId(Heap* heap, v8::RetainedObjectInfo* info); SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info);
static inline SnapshotObjectId GetNthGcSubrootId(int delta); static inline SnapshotObjectId GetNthGcSubrootId(int delta);
static const int kObjectIdStep = 2; static const int kObjectIdStep = 2;
...@@ -255,6 +252,7 @@ class HeapObjectsMap { ...@@ -255,6 +252,7 @@ class HeapObjectsMap {
int FindUntrackedObjects(); int FindUntrackedObjects();
void UpdateHeapObjectsMap(); void UpdateHeapObjectsMap();
void RemoveDeadEntries();
private: private:
struct EntryInfo { struct EntryInfo {
...@@ -274,8 +272,6 @@ class HeapObjectsMap { ...@@ -274,8 +272,6 @@ class HeapObjectsMap {
uint32_t count; uint32_t count;
}; };
void RemoveDeadEntries();
SnapshotObjectId next_id_; SnapshotObjectId next_id_;
HashMap entries_map_; HashMap entries_map_;
List<EntryInfo> entries_; List<EntryInfo> entries_;
...@@ -286,59 +282,6 @@ class HeapObjectsMap { ...@@ -286,59 +282,6 @@ class HeapObjectsMap {
}; };
class HeapSnapshotsCollection {
public:
explicit HeapSnapshotsCollection(Heap* heap);
~HeapSnapshotsCollection();
Heap* heap() const { return ids_.heap(); }
SnapshotObjectId PushHeapObjectsStats(OutputStream* stream) {
return ids_.PushHeapObjectsStats(stream);
}
void StartHeapObjectsTracking(bool track_allocations);
void StopHeapObjectsTracking();
HeapSnapshot* NewSnapshot(const char* name, unsigned uid);
void SnapshotGenerationFinished(HeapSnapshot* snapshot);
List<HeapSnapshot*>* snapshots() { return &snapshots_; }
void RemoveSnapshot(HeapSnapshot* snapshot);
StringsStorage* names() { return &names_; }
AllocationTracker* allocation_tracker() { return allocation_tracker_; }
SnapshotObjectId FindObjectId(Address object_addr) {
return ids_.FindEntry(object_addr);
}
SnapshotObjectId GetObjectId(Address object_addr, int object_size) {
return ids_.FindOrAddEntry(object_addr, object_size);
}
Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id);
void ObjectMoveEvent(Address from, Address to, int size) {
ids_.MoveObject(from, to, size);
}
void AllocationEvent(Address addr, int size);
void UpdateObjectSizeEvent(Address addr, int size) {
ids_.UpdateObjectSize(addr, size);
}
SnapshotObjectId last_assigned_id() const {
return ids_.last_assigned_id();
}
size_t GetUsedMemorySize() const;
int FindUntrackedObjects() { return ids_.FindUntrackedObjects(); }
private:
List<HeapSnapshot*> snapshots_;
StringsStorage names_;
// Mapping from HeapObject addresses to objects' uids.
HeapObjectsMap ids_;
AllocationTracker* allocation_tracker_;
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection);
};
// A typedef for referencing anything that can be snapshotted living // A typedef for referencing anything that can be snapshotted living
// in any kind of heap memory. // in any kind of heap memory.
typedef void* HeapThing; typedef void* HeapThing;
...@@ -531,7 +474,8 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -531,7 +474,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
Heap* heap_; Heap* heap_;
HeapSnapshot* snapshot_; HeapSnapshot* snapshot_;
HeapSnapshotsCollection* collection_; StringsStorage* names_;
HeapObjectsMap* heap_object_map_;
SnapshottingProgressReportingInterface* progress_; SnapshottingProgressReportingInterface* progress_;
SnapshotFillerInterface* filler_; SnapshotFillerInterface* filler_;
HeapObjectsSet objects_tags_; HeapObjectsSet objects_tags_;
...@@ -592,7 +536,7 @@ class NativeObjectsExplorer { ...@@ -592,7 +536,7 @@ class NativeObjectsExplorer {
Isolate* isolate_; Isolate* isolate_;
HeapSnapshot* snapshot_; HeapSnapshot* snapshot_;
HeapSnapshotsCollection* collection_; StringsStorage* names_;
SnapshottingProgressReportingInterface* progress_; SnapshottingProgressReportingInterface* progress_;
bool embedder_queried_; bool embedder_queried_;
HeapObjectsSet in_groups_; HeapObjectsSet in_groups_;
......
...@@ -196,6 +196,13 @@ class List { ...@@ -196,6 +196,13 @@ class List {
DISALLOW_COPY_AND_ASSIGN(List); DISALLOW_COPY_AND_ASSIGN(List);
}; };
template<typename T, class P>
size_t GetMemoryUsedByList(const List<T, P>& list) {
return list.length() * sizeof(T) + sizeof(list);
}
class Map; class Map;
class Type; class Type;
class Code; class Code;
......
...@@ -363,7 +363,7 @@ class HeapObjectsTracker { ...@@ -363,7 +363,7 @@ class HeapObjectsTracker {
~HeapObjectsTracker() { ~HeapObjectsTracker() {
i::Isolate::Current()->heap()->CollectAllAvailableGarbage(); i::Isolate::Current()->heap()->CollectAllAvailableGarbage();
CHECK_EQ(0, heap_profiler_->FindUntrackedObjects()); CHECK_EQ(0, heap_profiler_->heap_object_map()->FindUntrackedObjects());
heap_profiler_->StopHeapObjectsTracking(); heap_profiler_->StopHeapObjectsTracking();
} }
......
...@@ -2055,7 +2055,8 @@ void HeapProfilerExtension::FindUntrackedObjects( ...@@ -2055,7 +2055,8 @@ void HeapProfilerExtension::FindUntrackedObjects(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
i::HeapProfiler* heap_profiler = i::HeapProfiler* heap_profiler =
reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler()); reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler());
int untracked_objects = heap_profiler->FindUntrackedObjects(); int untracked_objects =
heap_profiler->heap_object_map()->FindUntrackedObjects();
args.GetReturnValue().Set(untracked_objects); args.GetReturnValue().Set(untracked_objects);
CHECK_EQ(0, untracked_objects); CHECK_EQ(0, untracked_objects);
} }
...@@ -2161,12 +2162,6 @@ static const char* record_trace_tree_source = ...@@ -2161,12 +2162,6 @@ static const char* record_trace_tree_source =
"for (var i = 0; i < 100; i++) start();\n"; "for (var i = 0; i < 100; i++) start();\n";
static i::HeapSnapshot* ToInternal(const v8::HeapSnapshot* snapshot) {
return const_cast<i::HeapSnapshot*>(
reinterpret_cast<const i::HeapSnapshot*>(snapshot));
}
static AllocationTraceNode* FindNode( static AllocationTraceNode* FindNode(
AllocationTracker* tracker, const Vector<const char*>& names) { AllocationTracker* tracker, const Vector<const char*>& names) {
AllocationTraceNode* node = tracker->trace_tree()->root(); AllocationTraceNode* node = tracker->trace_tree()->root();
...@@ -2201,10 +2196,8 @@ TEST(ArrayGrowLeftTrim) { ...@@ -2201,10 +2196,8 @@ TEST(ArrayGrowLeftTrim) {
" a.shift();\n"); " a.shift();\n");
const char* names[] = { "(anonymous function)" }; const char* names[] = { "(anonymous function)" };
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( AllocationTracker* tracker =
v8::String::NewFromUtf8(env->GetIsolate(), "Test1")); reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker();
i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection();
AllocationTracker* tracker = collection->allocation_tracker();
CHECK_NE(NULL, tracker); CHECK_NE(NULL, tracker);
// Resolve all function locations. // Resolve all function locations.
tracker->PrepareForSerialization(); tracker->PrepareForSerialization();
...@@ -2229,10 +2222,8 @@ TEST(TrackHeapAllocations) { ...@@ -2229,10 +2222,8 @@ TEST(TrackHeapAllocations) {
CompileRun(record_trace_tree_source); CompileRun(record_trace_tree_source);
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( AllocationTracker* tracker =
v8::String::NewFromUtf8(env->GetIsolate(), "Test")); reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker();
i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection();
AllocationTracker* tracker = collection->allocation_tracker();
CHECK_NE(NULL, tracker); CHECK_NE(NULL, tracker);
// Resolve all function locations. // Resolve all function locations.
tracker->PrepareForSerialization(); tracker->PrepareForSerialization();
...@@ -2282,10 +2273,8 @@ TEST(TrackBumpPointerAllocations) { ...@@ -2282,10 +2273,8 @@ TEST(TrackBumpPointerAllocations) {
CompileRun(inline_heap_allocation_source); CompileRun(inline_heap_allocation_source);
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( AllocationTracker* tracker =
v8::String::NewFromUtf8(env->GetIsolate(), "Test2")); reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker();
i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection();
AllocationTracker* tracker = collection->allocation_tracker();
CHECK_NE(NULL, tracker); CHECK_NE(NULL, tracker);
// Resolve all function locations. // Resolve all function locations.
tracker->PrepareForSerialization(); tracker->PrepareForSerialization();
...@@ -2310,10 +2299,8 @@ TEST(TrackBumpPointerAllocations) { ...@@ -2310,10 +2299,8 @@ TEST(TrackBumpPointerAllocations) {
CompileRun(inline_heap_allocation_source); CompileRun(inline_heap_allocation_source);
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( AllocationTracker* tracker =
v8::String::NewFromUtf8(env->GetIsolate(), "Test1")); reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker();
i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection();
AllocationTracker* tracker = collection->allocation_tracker();
CHECK_NE(NULL, tracker); CHECK_NE(NULL, tracker);
// Resolve all function locations. // Resolve all function locations.
tracker->PrepareForSerialization(); tracker->PrepareForSerialization();
......
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