| Index: src/heap-profiler.cc
|
| diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
|
| index 3d8e3364c90a8be445052865cf000270962a7146..6ae62723a7081eed316344cbe64042660296ef45 100644
|
| --- a/src/heap-profiler.cc
|
| +++ b/src/heap-profiler.cc
|
| @@ -28,28 +28,41 @@
|
| #include "v8.h"
|
|
|
| #include "heap-profiler.h"
|
| +
|
| +#include "allocation-tracker.h"
|
| #include "heap-snapshot-generator-inl.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| HeapProfiler::HeapProfiler(Heap* heap)
|
| - : snapshots_(new HeapSnapshotsCollection(heap)),
|
| + : ids_(new HeapObjectsMap(heap)),
|
| + names_(new StringsStorage(heap)),
|
| next_snapshot_uid_(1),
|
| - is_tracking_allocations_(false),
|
| is_tracking_object_moves_(false) {
|
| }
|
|
|
|
|
| +static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
|
| + delete *snapshot_ptr;
|
| +}
|
| +
|
| +
|
| HeapProfiler::~HeapProfiler() {
|
| - delete snapshots_;
|
| + snapshots_.Iterate(DeleteHeapSnapshot);
|
| + snapshots_.Clear();
|
| }
|
|
|
|
|
| void HeapProfiler::DeleteAllSnapshots() {
|
| - Heap* the_heap = heap();
|
| - delete snapshots_;
|
| - snapshots_ = new HeapSnapshotsCollection(the_heap);
|
| + snapshots_.Iterate(DeleteHeapSnapshot);
|
| + snapshots_.Clear();
|
| + names_.Reset(new StringsStorage(heap()));
|
| +}
|
| +
|
| +
|
| +void HeapProfiler::RemoveSnapshot(HeapSnapshot* snapshot) {
|
| + snapshots_.RemoveElement(snapshot);
|
| }
|
|
|
|
|
| @@ -76,15 +89,17 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(
|
| const char* name,
|
| v8::ActivityControl* control,
|
| 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());
|
| if (!generator.GenerateSnapshot()) {
|
| delete result;
|
| result = NULL;
|
| + } else {
|
| + snapshots_.Add(result);
|
| }
|
| }
|
| - snapshots_->SnapshotGenerationFinished(result);
|
| + ids_->RemoveDeadEntries();
|
| is_tracking_object_moves_ = true;
|
| return result;
|
| }
|
| @@ -94,69 +109,79 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(
|
| String* name,
|
| v8::ActivityControl* control,
|
| 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) {
|
| - snapshots_->StartHeapObjectsTracking(track_allocations);
|
| + ids_->UpdateHeapObjectsMap();
|
| is_tracking_object_moves_ = true;
|
| - ASSERT(!is_tracking_allocations_);
|
| + ASSERT(!is_tracking_allocations());
|
| if (track_allocations) {
|
| + allocation_tracker_.Reset(new AllocationTracker(*ids_, *names_));
|
| heap()->DisableInlineAllocation();
|
| - is_tracking_allocations_ = true;
|
| }
|
| }
|
|
|
|
|
| SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream) {
|
| - return snapshots_->PushHeapObjectsStats(stream);
|
| + return ids_->PushHeapObjectsStats(stream);
|
| }
|
|
|
|
|
| void HeapProfiler::StopHeapObjectsTracking() {
|
| - snapshots_->StopHeapObjectsTracking();
|
| - if (is_tracking_allocations_) {
|
| + ids_->StopHeapObjectsTracking();
|
| + if (is_tracking_allocations()) {
|
| + allocation_tracker_.Reset(NULL);
|
| heap()->EnableInlineAllocation();
|
| - is_tracking_allocations_ = false;
|
| }
|
| }
|
|
|
|
|
| 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() {
|
| - return snapshots_->snapshots()->length();
|
| + return snapshots_.length();
|
| }
|
|
|
|
|
| HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
|
| - return snapshots_->snapshots()->at(index);
|
| + return snapshots_.at(index);
|
| }
|
|
|
|
|
| SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) {
|
| if (!obj->IsHeapObject())
|
| 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) {
|
| - snapshots_->ObjectMoveEvent(from, to, size);
|
| + ids_->MoveObject(from, to, 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) {
|
| - snapshots_->UpdateObjectSizeEvent(addr, size);
|
| + ids_->UpdateObjectSize(addr, size);
|
| }
|
|
|
|
|
| @@ -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
|
|
|