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 #ifndef V8_PROFILER_HEAP_PROFILER_H_ | 5 #ifndef V8_PROFILER_HEAP_PROFILER_H_ |
6 #define V8_PROFILER_HEAP_PROFILER_H_ | 6 #define V8_PROFILER_HEAP_PROFILER_H_ |
7 | 7 |
| 8 #include "include/v8-util.h" |
8 #include "src/base/smart-pointers.h" | 9 #include "src/base/smart-pointers.h" |
9 #include "src/isolate.h" | 10 #include "src/isolate.h" |
10 #include "src/list.h" | 11 #include "src/list.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 // Forward declarations. | 16 // Forward declarations. |
16 class AllocationTracker; | 17 class AllocationTracker; |
17 class HeapObjectsMap; | 18 class HeapObjectsMap; |
18 class HeapSnapshot; | 19 class HeapSnapshot; |
| 20 class SamplingHeapProfiler; |
19 class StringsStorage; | 21 class StringsStorage; |
20 | 22 |
21 class HeapProfiler { | 23 class HeapProfiler { |
22 public: | 24 public: |
23 explicit HeapProfiler(Heap* heap); | 25 explicit HeapProfiler(Heap* heap); |
24 ~HeapProfiler(); | 26 ~HeapProfiler(); |
25 | 27 |
26 size_t GetMemorySizeUsedByProfiler(); | 28 size_t GetMemorySizeUsedByProfiler(); |
27 | 29 |
28 HeapSnapshot* TakeSnapshot( | 30 HeapSnapshot* TakeSnapshot( |
29 v8::ActivityControl* control, | 31 v8::ActivityControl* control, |
30 v8::HeapProfiler::ObjectNameResolver* resolver); | 32 v8::HeapProfiler::ObjectNameResolver* resolver); |
31 | 33 |
| 34 bool StartSamplingHeapProfiler(uint64_t sample_interval, int stack_depth); |
| 35 void StopSamplingHeapProfiler(); |
| 36 void GetHeapSample(OutputStream* stream); |
| 37 |
32 void StartHeapObjectsTracking(bool track_allocations); | 38 void StartHeapObjectsTracking(bool track_allocations); |
33 void StopHeapObjectsTracking(); | 39 void StopHeapObjectsTracking(); |
34 AllocationTracker* allocation_tracker() const { | 40 AllocationTracker* allocation_tracker() const { |
35 return allocation_tracker_.get(); | 41 return allocation_tracker_.get(); |
36 } | 42 } |
37 HeapObjectsMap* heap_object_map() const { return ids_.get(); } | 43 HeapObjectsMap* heap_object_map() const { return ids_.get(); } |
38 StringsStorage* names() const { return names_.get(); } | 44 StringsStorage* names() const { return names_.get(); } |
39 | 45 |
40 SnapshotObjectId PushHeapObjectsStats(OutputStream* stream, | 46 SnapshotObjectId PushHeapObjectsStats(OutputStream* stream, |
41 int64_t* timestamp_us); | 47 int64_t* timestamp_us); |
(...skipping 30 matching lines...) Expand all Loading... |
72 Heap* heap() const; | 78 Heap* heap() const; |
73 | 79 |
74 // Mapping from HeapObject addresses to objects' uids. | 80 // Mapping from HeapObject addresses to objects' uids. |
75 base::SmartPointer<HeapObjectsMap> ids_; | 81 base::SmartPointer<HeapObjectsMap> ids_; |
76 List<HeapSnapshot*> snapshots_; | 82 List<HeapSnapshot*> snapshots_; |
77 base::SmartPointer<StringsStorage> names_; | 83 base::SmartPointer<StringsStorage> names_; |
78 List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; | 84 List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; |
79 base::SmartPointer<AllocationTracker> allocation_tracker_; | 85 base::SmartPointer<AllocationTracker> allocation_tracker_; |
80 bool is_tracking_object_moves_; | 86 bool is_tracking_object_moves_; |
81 base::Mutex profiler_mutex_; | 87 base::Mutex profiler_mutex_; |
| 88 base::SmartPointer<SamplingHeapProfiler> sampling_heap_profiler_; |
| 89 }; |
| 90 |
| 91 template <int bytes> |
| 92 struct MaxDecimalDigitsIn; |
| 93 template <> |
| 94 struct MaxDecimalDigitsIn<4> { |
| 95 static const int kSigned = 11; |
| 96 static const int kUnsigned = 10; |
| 97 }; |
| 98 template <> |
| 99 struct MaxDecimalDigitsIn<8> { |
| 100 static const int kSigned = 20; |
| 101 static const int kUnsigned = 20; |
| 102 }; |
| 103 |
| 104 class OutputStreamWriter { |
| 105 public: |
| 106 explicit OutputStreamWriter(v8::OutputStream* stream) |
| 107 : stream_(stream), |
| 108 chunk_size_(stream->GetChunkSize()), |
| 109 chunk_(chunk_size_), |
| 110 chunk_pos_(0), |
| 111 aborted_(false) { |
| 112 DCHECK(chunk_size_ > 0); |
| 113 } |
| 114 bool aborted() { return aborted_; } |
| 115 void AddCharacter(char c) { |
| 116 DCHECK(c != '\0'); |
| 117 DCHECK(chunk_pos_ < chunk_size_); |
| 118 chunk_[chunk_pos_++] = c; |
| 119 MaybeWriteChunk(); |
| 120 } |
| 121 void AddString(const char* s) { AddSubstring(s, StrLength(s)); } |
| 122 void AddSubstring(const char* s, int n) { |
| 123 if (n <= 0) return; |
| 124 DCHECK(static_cast<size_t>(n) <= strlen(s)); |
| 125 const char* s_end = s + n; |
| 126 while (s < s_end) { |
| 127 int s_chunk_size = |
| 128 Min(chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); |
| 129 DCHECK(s_chunk_size > 0); |
| 130 MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size); |
| 131 s += s_chunk_size; |
| 132 chunk_pos_ += s_chunk_size; |
| 133 MaybeWriteChunk(); |
| 134 } |
| 135 } |
| 136 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } |
| 137 void Finalize() { |
| 138 if (aborted_) return; |
| 139 DCHECK(chunk_pos_ < chunk_size_); |
| 140 if (chunk_pos_ != 0) { |
| 141 WriteChunk(); |
| 142 } |
| 143 stream_->EndOfStream(); |
| 144 } |
| 145 |
| 146 private: |
| 147 template <typename T> |
| 148 void AddNumberImpl(T n, const char* format) { |
| 149 // Buffer for the longest value plus trailing \0 |
| 150 static const int kMaxNumberSize = |
| 151 MaxDecimalDigitsIn<sizeof(T)>::kUnsigned + 1; |
| 152 if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) { |
| 153 int result = |
| 154 SNPrintF(chunk_.SubVector(chunk_pos_, chunk_size_), format, n); |
| 155 DCHECK(result != -1); |
| 156 chunk_pos_ += result; |
| 157 MaybeWriteChunk(); |
| 158 } else { |
| 159 EmbeddedVector<char, kMaxNumberSize> buffer; |
| 160 int result = SNPrintF(buffer, format, n); |
| 161 USE(result); |
| 162 DCHECK(result != -1); |
| 163 AddString(buffer.start()); |
| 164 } |
| 165 } |
| 166 void MaybeWriteChunk() { |
| 167 DCHECK(chunk_pos_ <= chunk_size_); |
| 168 if (chunk_pos_ == chunk_size_) { |
| 169 WriteChunk(); |
| 170 } |
| 171 } |
| 172 void WriteChunk() { |
| 173 if (aborted_) return; |
| 174 if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) == |
| 175 v8::OutputStream::kAbort) |
| 176 aborted_ = true; |
| 177 chunk_pos_ = 0; |
| 178 } |
| 179 |
| 180 v8::OutputStream* stream_; |
| 181 int chunk_size_; |
| 182 ScopedVector<char> chunk_; |
| 183 int chunk_pos_; |
| 184 bool aborted_; |
82 }; | 185 }; |
83 | 186 |
84 } // namespace internal | 187 } // namespace internal |
85 } // namespace v8 | 188 } // namespace v8 |
86 | 189 |
87 #endif // V8_PROFILER_HEAP_PROFILER_H_ | 190 #endif // V8_PROFILER_HEAP_PROFILER_H_ |
OLD | NEW |