| OLD | NEW |
| 1 // Copyright 2009-2010 the V8 project authors. All rights reserved. | 1 // Copyright 2009-2010 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/profiler/heap-profiler.h" | 5 #include "src/profiler/heap-profiler.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/profiler/allocation-tracker.h" | 9 #include "src/profiler/allocation-tracker.h" |
| 10 #include "src/profiler/heap-snapshot-generator-inl.h" | 10 #include "src/profiler/heap-snapshot-generator-inl.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 HeapProfiler::~HeapProfiler() { | 28 HeapProfiler::~HeapProfiler() { |
| 29 snapshots_.Iterate(DeleteHeapSnapshot); | 29 snapshots_.Iterate(DeleteHeapSnapshot); |
| 30 snapshots_.Clear(); | 30 snapshots_.Clear(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 void HeapProfiler::DeleteAllSnapshots() { | 34 void HeapProfiler::DeleteAllSnapshots() { |
| 35 snapshots_.Iterate(DeleteHeapSnapshot); | 35 snapshots_.Iterate(DeleteHeapSnapshot); |
| 36 snapshots_.Clear(); | 36 snapshots_.Clear(); |
| 37 names_.Reset(new StringsStorage(heap())); | 37 names_.reset(new StringsStorage(heap())); |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 void HeapProfiler::RemoveSnapshot(HeapSnapshot* snapshot) { | 41 void HeapProfiler::RemoveSnapshot(HeapSnapshot* snapshot) { |
| 42 snapshots_.RemoveElement(snapshot); | 42 snapshots_.RemoveElement(snapshot); |
| 43 } | 43 } |
| 44 | 44 |
| 45 | 45 |
| 46 void HeapProfiler::DefineWrapperClass( | 46 void HeapProfiler::DefineWrapperClass( |
| 47 uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback) { | 47 uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 return result; | 84 return result; |
| 85 } | 85 } |
| 86 | 86 |
| 87 bool HeapProfiler::StartSamplingHeapProfiler( | 87 bool HeapProfiler::StartSamplingHeapProfiler( |
| 88 uint64_t sample_interval, int stack_depth, | 88 uint64_t sample_interval, int stack_depth, |
| 89 v8::HeapProfiler::SamplingFlags flags) { | 89 v8::HeapProfiler::SamplingFlags flags) { |
| 90 if (sampling_heap_profiler_.get()) { | 90 if (sampling_heap_profiler_.get()) { |
| 91 return false; | 91 return false; |
| 92 } | 92 } |
| 93 sampling_heap_profiler_.Reset(new SamplingHeapProfiler( | 93 sampling_heap_profiler_.reset(new SamplingHeapProfiler( |
| 94 heap(), names_.get(), sample_interval, stack_depth, flags)); | 94 heap(), names_.get(), sample_interval, stack_depth, flags)); |
| 95 return true; | 95 return true; |
| 96 } | 96 } |
| 97 | 97 |
| 98 | 98 |
| 99 void HeapProfiler::StopSamplingHeapProfiler() { | 99 void HeapProfiler::StopSamplingHeapProfiler() { |
| 100 sampling_heap_profiler_.Reset(nullptr); | 100 sampling_heap_profiler_.reset(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 v8::AllocationProfile* HeapProfiler::GetAllocationProfile() { | 104 v8::AllocationProfile* HeapProfiler::GetAllocationProfile() { |
| 105 if (sampling_heap_profiler_.get()) { | 105 if (sampling_heap_profiler_.get()) { |
| 106 return sampling_heap_profiler_->GetAllocationProfile(); | 106 return sampling_heap_profiler_->GetAllocationProfile(); |
| 107 } else { | 107 } else { |
| 108 return nullptr; | 108 return nullptr; |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 void HeapProfiler::StartHeapObjectsTracking(bool track_allocations) { | 113 void HeapProfiler::StartHeapObjectsTracking(bool track_allocations) { |
| 114 ids_->UpdateHeapObjectsMap(); | 114 ids_->UpdateHeapObjectsMap(); |
| 115 is_tracking_object_moves_ = true; | 115 is_tracking_object_moves_ = true; |
| 116 DCHECK(!is_tracking_allocations()); | 116 DCHECK(!is_tracking_allocations()); |
| 117 if (track_allocations) { | 117 if (track_allocations) { |
| 118 allocation_tracker_.Reset(new AllocationTracker(ids_.get(), names_.get())); | 118 allocation_tracker_.reset(new AllocationTracker(ids_.get(), names_.get())); |
| 119 heap()->DisableInlineAllocation(); | 119 heap()->DisableInlineAllocation(); |
| 120 heap()->isolate()->debug()->feature_tracker()->Track( | 120 heap()->isolate()->debug()->feature_tracker()->Track( |
| 121 DebugFeatureTracker::kAllocationTracking); | 121 DebugFeatureTracker::kAllocationTracking); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream, | 126 SnapshotObjectId HeapProfiler::PushHeapObjectsStats(OutputStream* stream, |
| 127 int64_t* timestamp_us) { | 127 int64_t* timestamp_us) { |
| 128 return ids_->PushHeapObjectsStats(stream, timestamp_us); | 128 return ids_->PushHeapObjectsStats(stream, timestamp_us); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void HeapProfiler::StopHeapObjectsTracking() { | 132 void HeapProfiler::StopHeapObjectsTracking() { |
| 133 ids_->StopHeapObjectsTracking(); | 133 ids_->StopHeapObjectsTracking(); |
| 134 if (is_tracking_allocations()) { | 134 if (is_tracking_allocations()) { |
| 135 allocation_tracker_.Reset(NULL); | 135 allocation_tracker_.reset(); |
| 136 heap()->EnableInlineAllocation(); | 136 heap()->EnableInlineAllocation(); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 size_t HeapProfiler::GetMemorySizeUsedByProfiler() { | 141 size_t HeapProfiler::GetMemorySizeUsedByProfiler() { |
| 142 size_t size = sizeof(*this); | 142 size_t size = sizeof(*this); |
| 143 size += names_->GetUsedMemorySize(); | 143 size += names_->GetUsedMemorySize(); |
| 144 size += ids_->GetUsedMemorySize(); | 144 size += ids_->GetUsedMemorySize(); |
| 145 size += GetMemoryUsedByList(snapshots_); | 145 size += GetMemoryUsedByList(snapshots_); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 163 SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) { | 163 SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) { |
| 164 if (!obj->IsHeapObject()) | 164 if (!obj->IsHeapObject()) |
| 165 return v8::HeapProfiler::kUnknownObjectId; | 165 return v8::HeapProfiler::kUnknownObjectId; |
| 166 return ids_->FindEntry(HeapObject::cast(*obj)->address()); | 166 return ids_->FindEntry(HeapObject::cast(*obj)->address()); |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 void HeapProfiler::ObjectMoveEvent(Address from, Address to, int size) { | 170 void HeapProfiler::ObjectMoveEvent(Address from, Address to, int size) { |
| 171 base::LockGuard<base::Mutex> guard(&profiler_mutex_); | 171 base::LockGuard<base::Mutex> guard(&profiler_mutex_); |
| 172 bool known_object = ids_->MoveObject(from, to, size); | 172 bool known_object = ids_->MoveObject(from, to, size); |
| 173 if (!known_object && !allocation_tracker_.is_empty()) { | 173 if (!known_object && allocation_tracker_) { |
| 174 allocation_tracker_->address_to_trace()->MoveObject(from, to, size); | 174 allocation_tracker_->address_to_trace()->MoveObject(from, to, size); |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 void HeapProfiler::AllocationEvent(Address addr, int size) { | 179 void HeapProfiler::AllocationEvent(Address addr, int size) { |
| 180 DisallowHeapAllocation no_allocation; | 180 DisallowHeapAllocation no_allocation; |
| 181 if (!allocation_tracker_.is_empty()) { | 181 if (allocation_tracker_) { |
| 182 allocation_tracker_->AllocationEvent(addr, size); | 182 allocation_tracker_->AllocationEvent(addr, size); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 | 185 |
| 186 | 186 |
| 187 void HeapProfiler::UpdateObjectSizeEvent(Address addr, int size) { | 187 void HeapProfiler::UpdateObjectSizeEvent(Address addr, int size) { |
| 188 ids_->UpdateObjectSize(addr, size); | 188 ids_->UpdateObjectSize(addr, size); |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 207 DCHECK(object == NULL); | 207 DCHECK(object == NULL); |
| 208 object = obj; | 208 object = obj; |
| 209 // Can't break -- kFilterUnreachable requires full heap traversal. | 209 // Can't break -- kFilterUnreachable requires full heap traversal. |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>(); | 212 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>(); |
| 213 } | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 void HeapProfiler::ClearHeapObjectMap() { | 216 void HeapProfiler::ClearHeapObjectMap() { |
| 217 ids_.Reset(new HeapObjectsMap(heap())); | 217 ids_.reset(new HeapObjectsMap(heap())); |
| 218 if (!is_tracking_allocations()) is_tracking_object_moves_ = false; | 218 if (!is_tracking_allocations()) is_tracking_object_moves_ = false; |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 Heap* HeapProfiler::heap() const { return ids_->heap(); } | 222 Heap* HeapProfiler::heap() const { return ids_->heap(); } |
| 223 | 223 |
| 224 | 224 |
| 225 } // namespace internal | 225 } // namespace internal |
| 226 } // namespace v8 | 226 } // namespace v8 |
| OLD | NEW |