Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: src/heap-profiler.h

Issue 7247018: Remove obsolete aggregating and non-working producers heap profilers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2009-2010 the V8 project authors. All rights reserved. 1 // Copyright 2009-2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_HEAP_PROFILER_H_ 28 #ifndef V8_HEAP_PROFILER_H_
29 #define V8_HEAP_PROFILER_H_ 29 #define V8_HEAP_PROFILER_H_
30 30
31 #include "allocation.h"
32 #include "isolate.h" 31 #include "isolate.h"
33 #include "zone-inl.h"
34 32
35 namespace v8 { 33 namespace v8 {
36 namespace internal { 34 namespace internal {
37 35
38 #ifdef ENABLE_LOGGING_AND_PROFILING 36 #ifdef ENABLE_LOGGING_AND_PROFILING
39 37
40 class HeapSnapshot; 38 class HeapSnapshot;
41 class HeapSnapshotsCollection; 39 class HeapSnapshotsCollection;
42 40
43 #define HEAP_PROFILE(heap, call) \ 41 #define HEAP_PROFILE(heap, call) \
(...skipping 30 matching lines...) Expand all
74 72
75 void DefineWrapperClass( 73 void DefineWrapperClass(
76 uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback); 74 uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback);
77 75
78 v8::RetainedObjectInfo* ExecuteWrapperClassCallback(uint16_t class_id, 76 v8::RetainedObjectInfo* ExecuteWrapperClassCallback(uint16_t class_id,
79 Object** wrapper); 77 Object** wrapper);
80 INLINE(bool is_profiling()) { 78 INLINE(bool is_profiling()) {
81 return snapshots_->is_tracking_objects(); 79 return snapshots_->is_tracking_objects();
82 } 80 }
83 81
84 // Obsolete interface.
85 // Write a single heap sample to the log file.
86 static void WriteSample();
87
88 private: 82 private:
89 HeapProfiler(); 83 HeapProfiler();
90 ~HeapProfiler(); 84 ~HeapProfiler();
91 HeapSnapshot* TakeSnapshotImpl(const char* name, 85 HeapSnapshot* TakeSnapshotImpl(const char* name,
92 int type, 86 int type,
93 v8::ActivityControl* control); 87 v8::ActivityControl* control);
94 HeapSnapshot* TakeSnapshotImpl(String* name, 88 HeapSnapshot* TakeSnapshotImpl(String* name,
95 int type, 89 int type,
96 v8::ActivityControl* control); 90 v8::ActivityControl* control);
97 void ResetSnapshots(); 91 void ResetSnapshots();
98 92
99 HeapSnapshotsCollection* snapshots_; 93 HeapSnapshotsCollection* snapshots_;
100 unsigned next_snapshot_uid_; 94 unsigned next_snapshot_uid_;
101 List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; 95 List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_;
102 96
103 #endif // ENABLE_LOGGING_AND_PROFILING 97 #endif // ENABLE_LOGGING_AND_PROFILING
104 }; 98 };
105 99
106
107 #ifdef ENABLE_LOGGING_AND_PROFILING
108
109 // JSObjectsCluster describes a group of JS objects that are
110 // considered equivalent in terms of a particular profile.
111 class JSObjectsCluster BASE_EMBEDDED {
112 public:
113 // These special cases are used in retainer profile.
114 enum SpecialCase {
115 ROOTS = 1,
116 GLOBAL_PROPERTY = 2,
117 CODE = 3,
118 SELF = 100 // This case is used in ClustersCoarser only.
119 };
120
121 JSObjectsCluster() : constructor_(NULL), instance_(NULL) {}
122 explicit JSObjectsCluster(String* constructor)
123 : constructor_(constructor), instance_(NULL) {}
124 explicit JSObjectsCluster(SpecialCase special)
125 : constructor_(FromSpecialCase(special)), instance_(NULL) {}
126 JSObjectsCluster(String* constructor, Object* instance)
127 : constructor_(constructor), instance_(instance) {}
128
129 static int CompareConstructors(const JSObjectsCluster& a,
130 const JSObjectsCluster& b) {
131 // Strings are unique, so it is sufficient to compare their pointers.
132 return a.constructor_ == b.constructor_ ? 0
133 : (a.constructor_ < b.constructor_ ? -1 : 1);
134 }
135 static int Compare(const JSObjectsCluster& a, const JSObjectsCluster& b) {
136 // Strings are unique, so it is sufficient to compare their pointers.
137 const int cons_cmp = CompareConstructors(a, b);
138 return cons_cmp == 0 ?
139 (a.instance_ == b.instance_ ? 0 : (a.instance_ < b.instance_ ? -1 : 1))
140 : cons_cmp;
141 }
142 static int Compare(const JSObjectsCluster* a, const JSObjectsCluster* b) {
143 return Compare(*a, *b);
144 }
145
146 bool is_null() const { return constructor_ == NULL; }
147 bool can_be_coarsed() const { return instance_ != NULL; }
148 String* constructor() const { return constructor_; }
149 Object* instance() const { return instance_; }
150
151 const char* GetSpecialCaseName() const;
152 void Print(StringStream* accumulator) const;
153 // Allows null clusters to be printed.
154 void DebugPrint(StringStream* accumulator) const;
155
156 private:
157 static String* FromSpecialCase(SpecialCase special) {
158 // We use symbols that are illegal JS identifiers to identify special cases.
159 // Their actual value is irrelevant for us.
160 switch (special) {
161 case ROOTS: return HEAP->result_symbol();
162 case GLOBAL_PROPERTY: return HEAP->catch_var_symbol();
163 case CODE: return HEAP->code_symbol();
164 case SELF: return HEAP->this_symbol();
165 default:
166 UNREACHABLE();
167 return NULL;
168 }
169 }
170
171 String* constructor_;
172 Object* instance_;
173 };
174
175
176 struct JSObjectsClusterTreeConfig {
177 typedef JSObjectsCluster Key;
178 typedef NumberAndSizeInfo Value;
179 static const Key kNoKey;
180 static const Value kNoValue;
181 static int Compare(const Key& a, const Key& b) {
182 return Key::Compare(a, b);
183 }
184 };
185 typedef ZoneSplayTree<JSObjectsClusterTreeConfig> JSObjectsClusterTree;
186
187
188 // ConstructorHeapProfile is responsible for gathering and logging
189 // "constructor profile" of JS objects allocated on heap.
190 // It is run during garbage collection cycle, thus it doesn't need
191 // to use handles.
192 class ConstructorHeapProfile BASE_EMBEDDED {
193 public:
194 ConstructorHeapProfile();
195 virtual ~ConstructorHeapProfile() {}
196 void CollectStats(HeapObject* obj);
197 void PrintStats();
198
199 template<class Callback>
200 void ForEach(Callback* callback) { js_objects_info_tree_.ForEach(callback); }
201 // Used by ZoneSplayTree::ForEach. Made virtual to allow overriding in tests.
202 virtual void Call(const JSObjectsCluster& cluster,
203 const NumberAndSizeInfo& number_and_size);
204
205 private:
206 ZoneScope zscope_;
207 JSObjectsClusterTree js_objects_info_tree_;
208 };
209
210
211 // JSObjectsRetainerTree is used to represent retainer graphs using
212 // adjacency list form:
213 //
214 // Cluster -> (Cluster -> NumberAndSizeInfo)
215 //
216 // Subordinate splay trees are stored by pointer. They are zone-allocated,
217 // so it isn't needed to manage their lifetime.
218 //
219 struct JSObjectsRetainerTreeConfig {
220 typedef JSObjectsCluster Key;
221 typedef JSObjectsClusterTree* Value;
222 static const Key kNoKey;
223 static const Value kNoValue;
224 static int Compare(const Key& a, const Key& b) {
225 return Key::Compare(a, b);
226 }
227 };
228 typedef ZoneSplayTree<JSObjectsRetainerTreeConfig> JSObjectsRetainerTree;
229
230
231 class ClustersCoarser BASE_EMBEDDED {
232 public:
233 ClustersCoarser();
234
235 // Processes a given retainer graph.
236 void Process(JSObjectsRetainerTree* tree);
237
238 // Returns an equivalent cluster (can be the cluster itself).
239 // If the given cluster doesn't have an equivalent, returns null cluster.
240 JSObjectsCluster GetCoarseEquivalent(const JSObjectsCluster& cluster);
241 // Returns whether a cluster can be substitued with an equivalent and thus,
242 // skipped in some cases.
243 bool HasAnEquivalent(const JSObjectsCluster& cluster);
244
245 // Used by JSObjectsRetainerTree::ForEach.
246 void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree);
247 void Call(const JSObjectsCluster& cluster,
248 const NumberAndSizeInfo& number_and_size);
249
250 private:
251 // Stores a list of back references for a cluster.
252 struct ClusterBackRefs {
253 explicit ClusterBackRefs(const JSObjectsCluster& cluster_);
254 ClusterBackRefs(const ClusterBackRefs& src);
255 ClusterBackRefs& operator=(const ClusterBackRefs& src);
256
257 static int Compare(const ClusterBackRefs& a, const ClusterBackRefs& b);
258 void SortRefs() { refs.Sort(JSObjectsCluster::Compare); }
259 static void SortRefsIterator(ClusterBackRefs* ref) { ref->SortRefs(); }
260
261 JSObjectsCluster cluster;
262 ZoneList<JSObjectsCluster> refs;
263 };
264 typedef ZoneList<ClusterBackRefs> SimilarityList;
265
266 // A tree for storing a list of equivalents for a cluster.
267 struct ClusterEqualityConfig {
268 typedef JSObjectsCluster Key;
269 typedef JSObjectsCluster Value;
270 static const Key kNoKey;
271 static const Value kNoValue;
272 static int Compare(const Key& a, const Key& b) {
273 return Key::Compare(a, b);
274 }
275 };
276 typedef ZoneSplayTree<ClusterEqualityConfig> EqualityTree;
277
278 static int ClusterBackRefsCmp(const ClusterBackRefs* a,
279 const ClusterBackRefs* b) {
280 return ClusterBackRefs::Compare(*a, *b);
281 }
282 int DoProcess(JSObjectsRetainerTree* tree);
283 int FillEqualityTree();
284
285 static const int kInitialBackrefsListCapacity = 2;
286 static const int kInitialSimilarityListCapacity = 2000;
287 // Number of passes for finding equivalents. Limits the length of paths
288 // that can be considered equivalent.
289 static const int kMaxPassesCount = 10;
290
291 ZoneScope zscope_;
292 SimilarityList sim_list_;
293 EqualityTree eq_tree_;
294 ClusterBackRefs* current_pair_;
295 JSObjectsRetainerTree* current_set_;
296 const JSObjectsCluster* self_;
297 };
298
299
300 // RetainerHeapProfile is responsible for gathering and logging
301 // "retainer profile" of JS objects allocated on heap.
302 // It is run during garbage collection cycle, thus it doesn't need
303 // to use handles.
304 class RetainerTreeAggregator;
305
306 class RetainerHeapProfile BASE_EMBEDDED {
307 public:
308 class Printer {
309 public:
310 virtual ~Printer() {}
311 virtual void PrintRetainers(const JSObjectsCluster& cluster,
312 const StringStream& retainers) = 0;
313 };
314
315 RetainerHeapProfile();
316 ~RetainerHeapProfile();
317
318 RetainerTreeAggregator* aggregator() { return aggregator_; }
319 ClustersCoarser* coarser() { return &coarser_; }
320 JSObjectsRetainerTree* retainers_tree() { return &retainers_tree_; }
321
322 void CollectStats(HeapObject* obj);
323 void CoarseAndAggregate();
324 void PrintStats();
325 void DebugPrintStats(Printer* printer);
326 void StoreReference(const JSObjectsCluster& cluster, HeapObject* ref);
327
328 private:
329 ZoneScope zscope_;
330 JSObjectsRetainerTree retainers_tree_;
331 ClustersCoarser coarser_;
332 RetainerTreeAggregator* aggregator_;
333 };
334
335
336 class AggregatedHeapSnapshot {
337 public:
338 AggregatedHeapSnapshot();
339 ~AggregatedHeapSnapshot();
340
341 HistogramInfo* info() { return info_; }
342 ConstructorHeapProfile* js_cons_profile() { return &js_cons_profile_; }
343 RetainerHeapProfile* js_retainer_profile() { return &js_retainer_profile_; }
344
345 private:
346 HistogramInfo* info_;
347 ConstructorHeapProfile js_cons_profile_;
348 RetainerHeapProfile js_retainer_profile_;
349 };
350
351
352 class HeapEntriesMap;
353 class HeapEntriesAllocator;
354
355 class AggregatedHeapSnapshotGenerator {
356 public:
357 explicit AggregatedHeapSnapshotGenerator(AggregatedHeapSnapshot* snapshot);
358 void GenerateSnapshot();
359 void FillHeapSnapshot(HeapSnapshot* snapshot);
360
361 static const int kAllStringsType = LAST_TYPE + 1;
362
363 private:
364 void CalculateStringsStats();
365 void CollectStats(HeapObject* obj);
366 template<class Iterator>
367 void IterateRetainers(
368 HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map);
369
370 AggregatedHeapSnapshot* agg_snapshot_;
371 };
372
373
374 class ProducerHeapProfile {
375 public:
376 void Setup();
377 void RecordJSObjectAllocation(Object* obj) {
378 if (FLAG_log_producers) DoRecordJSObjectAllocation(obj);
379 }
380
381 private:
382 ProducerHeapProfile() : can_log_(false) { }
383
384 void DoRecordJSObjectAllocation(Object* obj);
385 Isolate* isolate_;
386 bool can_log_;
387
388 friend class Isolate;
389
390 DISALLOW_COPY_AND_ASSIGN(ProducerHeapProfile);
391 };
392
393 #endif // ENABLE_LOGGING_AND_PROFILING
394
395 } } // namespace v8::internal 100 } } // namespace v8::internal
396 101
397 #endif // V8_HEAP_PROFILER_H_ 102 #endif // V8_HEAP_PROFILER_H_
OLDNEW
« src/api.cc ('K') | « src/heap.cc ('k') | src/heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698