diff options
Diffstat (limited to 'chromium/v8/src/heap-profiler.cc')
-rw-r--r-- | chromium/v8/src/heap-profiler.cc | 134 |
1 files changed, 81 insertions, 53 deletions
diff --git a/chromium/v8/src/heap-profiler.cc b/chromium/v8/src/heap-profiler.cc index 3d8e3364c90..e576d3b23e9 100644 --- a/chromium/v8/src/heap-profiler.cc +++ b/chromium/v8/src/heap-profiler.cc @@ -1,55 +1,45 @@ // Copyright 2009-2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" - -#include "heap-profiler.h" -#include "heap-snapshot-generator-inl.h" +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/heap-profiler.h" + +#include "src/allocation-tracker.h" +#include "src/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 +66,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 +86,82 @@ 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_.get(), names_.get())); 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); + bool known_object = ids_->MoveObject(from, to, size); + if (!known_object && !allocation_tracker_.is_empty()) { + allocation_tracker_->address_to_trace()->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 +172,27 @@ void HeapProfiler::SetRetainedObjectInfo(UniqueId id, } +Handle<HeapObject> HeapProfiler::FindHeapObjectById(SnapshotObjectId id) { + 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 HeapProfiler::ClearHeapObjectMap() { + ids_.Reset(new HeapObjectsMap(heap())); + if (!is_tracking_allocations()) is_tracking_object_moves_ = false; +} + + } } // namespace v8::internal |