OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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_PROFILE_GENERATOR_H_ | 5 #ifndef V8_PROFILER_PROFILE_GENERATOR_H_ |
6 #define V8_PROFILER_PROFILE_GENERATOR_H_ | 6 #define V8_PROFILER_PROFILE_GENERATOR_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include "src/allocation.h" | 9 #include "src/allocation.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 std::map<int, std::vector<DeoptInlinedFrame>> deopt_inlined_frames_; | 176 std::map<int, std::vector<DeoptInlinedFrame>> deopt_inlined_frames_; |
177 | 177 |
178 DISALLOW_COPY_AND_ASSIGN(CodeEntry); | 178 DISALLOW_COPY_AND_ASSIGN(CodeEntry); |
179 }; | 179 }; |
180 | 180 |
181 | 181 |
182 class ProfileTree; | 182 class ProfileTree; |
183 | 183 |
184 class ProfileNode { | 184 class ProfileNode { |
185 public: | 185 public: |
186 inline ProfileNode(ProfileTree* tree, CodeEntry* entry); | 186 inline ProfileNode(ProfileTree* tree, CodeEntry* entry, ProfileNode* parent); |
187 | 187 |
188 ProfileNode* FindChild(CodeEntry* entry); | 188 ProfileNode* FindChild(CodeEntry* entry); |
189 ProfileNode* FindOrAddChild(CodeEntry* entry); | 189 ProfileNode* FindOrAddChild(CodeEntry* entry); |
190 void IncrementSelfTicks() { ++self_ticks_; } | 190 void IncrementSelfTicks() { ++self_ticks_; } |
191 void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } | 191 void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } |
192 void IncrementLineTicks(int src_line); | 192 void IncrementLineTicks(int src_line); |
193 | 193 |
194 CodeEntry* entry() const { return entry_; } | 194 CodeEntry* entry() const { return entry_; } |
195 unsigned self_ticks() const { return self_ticks_; } | 195 unsigned self_ticks() const { return self_ticks_; } |
196 const List<ProfileNode*>* children() const { return &children_list_; } | 196 const List<ProfileNode*>* children() const { return &children_list_; } |
197 unsigned id() const { return id_; } | 197 unsigned id() const { return id_; } |
198 unsigned function_id() const; | 198 unsigned function_id() const; |
| 199 ProfileNode* parent() const { return parent_; } |
199 unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); } | 200 unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); } |
200 bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, | 201 bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, |
201 unsigned int length) const; | 202 unsigned int length) const; |
202 void CollectDeoptInfo(CodeEntry* entry); | 203 void CollectDeoptInfo(CodeEntry* entry); |
203 const std::vector<CpuProfileDeoptInfo>& deopt_infos() const { | 204 const std::vector<CpuProfileDeoptInfo>& deopt_infos() const { |
204 return deopt_infos_; | 205 return deopt_infos_; |
205 } | 206 } |
206 Isolate* isolate() const; | 207 Isolate* isolate() const; |
207 | 208 |
208 void Print(int indent); | 209 void Print(int indent); |
209 | 210 |
210 static bool CodeEntriesMatch(void* entry1, void* entry2) { | 211 static bool CodeEntriesMatch(void* entry1, void* entry2) { |
211 return reinterpret_cast<CodeEntry*>(entry1) | 212 return reinterpret_cast<CodeEntry*>(entry1) |
212 ->IsSameFunctionAs(reinterpret_cast<CodeEntry*>(entry2)); | 213 ->IsSameFunctionAs(reinterpret_cast<CodeEntry*>(entry2)); |
213 } | 214 } |
214 | 215 |
215 private: | 216 private: |
216 static uint32_t CodeEntryHash(CodeEntry* entry) { return entry->GetHash(); } | 217 static uint32_t CodeEntryHash(CodeEntry* entry) { return entry->GetHash(); } |
217 | 218 |
218 static bool LineTickMatch(void* a, void* b) { return a == b; } | 219 static bool LineTickMatch(void* a, void* b) { return a == b; } |
219 | 220 |
220 ProfileTree* tree_; | 221 ProfileTree* tree_; |
221 CodeEntry* entry_; | 222 CodeEntry* entry_; |
222 unsigned self_ticks_; | 223 unsigned self_ticks_; |
223 // Mapping from CodeEntry* to ProfileNode* | 224 // Mapping from CodeEntry* to ProfileNode* |
224 base::CustomMatcherHashMap children_; | 225 base::CustomMatcherHashMap children_; |
225 List<ProfileNode*> children_list_; | 226 List<ProfileNode*> children_list_; |
| 227 ProfileNode* parent_; |
226 unsigned id_; | 228 unsigned id_; |
227 base::CustomMatcherHashMap line_ticks_; | 229 base::CustomMatcherHashMap line_ticks_; |
228 | 230 |
229 std::vector<CpuProfileDeoptInfo> deopt_infos_; | 231 std::vector<CpuProfileDeoptInfo> deopt_infos_; |
230 | 232 |
231 DISALLOW_COPY_AND_ASSIGN(ProfileNode); | 233 DISALLOW_COPY_AND_ASSIGN(ProfileNode); |
232 }; | 234 }; |
233 | 235 |
234 | 236 |
235 class ProfileTree { | 237 class ProfileTree { |
236 public: | 238 public: |
237 explicit ProfileTree(Isolate* isolate); | 239 explicit ProfileTree(Isolate* isolate); |
238 ~ProfileTree(); | 240 ~ProfileTree(); |
239 | 241 |
240 ProfileNode* AddPathFromEnd( | 242 ProfileNode* AddPathFromEnd( |
241 const std::vector<CodeEntry*>& path, | 243 const std::vector<CodeEntry*>& path, |
242 int src_line = v8::CpuProfileNode::kNoLineNumberInfo, | 244 int src_line = v8::CpuProfileNode::kNoLineNumberInfo, |
243 bool update_stats = true); | 245 bool update_stats = true); |
244 ProfileNode* root() const { return root_; } | 246 ProfileNode* root() const { return root_; } |
245 unsigned next_node_id() { return next_node_id_++; } | 247 unsigned next_node_id() { return next_node_id_++; } |
246 unsigned GetFunctionId(const ProfileNode* node); | 248 unsigned GetFunctionId(const ProfileNode* node); |
247 | 249 |
248 void Print() { | 250 void Print() { |
249 root_->Print(0); | 251 root_->Print(0); |
250 } | 252 } |
251 | 253 |
252 Isolate* isolate() const { return isolate_; } | 254 Isolate* isolate() const { return isolate_; } |
253 | 255 |
| 256 void EnqueueNode(const ProfileNode* node) { pending_nodes_.push_back(node); } |
| 257 size_t pending_nodes_count() const { return pending_nodes_.size(); } |
| 258 std::vector<const ProfileNode*> TakePendingNodes() { |
| 259 return std::move(pending_nodes_); |
| 260 } |
| 261 |
254 private: | 262 private: |
255 template <typename Callback> | 263 template <typename Callback> |
256 void TraverseDepthFirst(Callback* callback); | 264 void TraverseDepthFirst(Callback* callback); |
257 | 265 |
| 266 std::vector<const ProfileNode*> pending_nodes_; |
| 267 |
258 CodeEntry root_entry_; | 268 CodeEntry root_entry_; |
259 unsigned next_node_id_; | 269 unsigned next_node_id_; |
260 ProfileNode* root_; | 270 ProfileNode* root_; |
261 Isolate* isolate_; | 271 Isolate* isolate_; |
262 | 272 |
263 unsigned next_function_id_; | 273 unsigned next_function_id_; |
264 base::CustomMatcherHashMap function_ids_; | 274 base::CustomMatcherHashMap function_ids_; |
265 | 275 |
266 DISALLOW_COPY_AND_ASSIGN(ProfileTree); | 276 DISALLOW_COPY_AND_ASSIGN(ProfileTree); |
267 }; | 277 }; |
268 | 278 |
269 | 279 |
270 class CpuProfile { | 280 class CpuProfile { |
271 public: | 281 public: |
272 CpuProfile(CpuProfiler* profiler, const char* title, bool record_samples); | 282 CpuProfile(CpuProfiler* profiler, const char* title, bool record_samples); |
273 | 283 |
274 // Add pc -> ... -> main() call path to the profile. | 284 // Add pc -> ... -> main() call path to the profile. |
275 void AddPath(base::TimeTicks timestamp, const std::vector<CodeEntry*>& path, | 285 void AddPath(base::TimeTicks timestamp, const std::vector<CodeEntry*>& path, |
276 int src_line, bool update_stats); | 286 int src_line, bool update_stats); |
277 void CalculateTotalTicksAndSamplingRate(); | 287 void FinishProfile(); |
278 | 288 |
279 const char* title() const { return title_; } | 289 const char* title() const { return title_; } |
280 const ProfileTree* top_down() const { return &top_down_; } | 290 const ProfileTree* top_down() const { return &top_down_; } |
281 | 291 |
282 int samples_count() const { return samples_.length(); } | 292 int samples_count() const { return samples_.length(); } |
283 ProfileNode* sample(int index) const { return samples_.at(index); } | 293 ProfileNode* sample(int index) const { return samples_.at(index); } |
284 base::TimeTicks sample_timestamp(int index) const { | 294 base::TimeTicks sample_timestamp(int index) const { |
285 return timestamps_.at(index); | 295 return timestamps_.at(index); |
286 } | 296 } |
287 | 297 |
288 base::TimeTicks start_time() const { return start_time_; } | 298 base::TimeTicks start_time() const { return start_time_; } |
289 base::TimeTicks end_time() const { return end_time_; } | 299 base::TimeTicks end_time() const { return end_time_; } |
290 CpuProfiler* cpu_profiler() const { return profiler_; } | 300 CpuProfiler* cpu_profiler() const { return profiler_; } |
291 | 301 |
292 void UpdateTicksScale(); | 302 void UpdateTicksScale(); |
293 | 303 |
294 void Print(); | 304 void Print(); |
295 | 305 |
296 private: | 306 private: |
| 307 void StreamPendingTraceEvents(); |
| 308 |
297 const char* title_; | 309 const char* title_; |
298 bool record_samples_; | 310 bool record_samples_; |
299 base::TimeTicks start_time_; | 311 base::TimeTicks start_time_; |
300 base::TimeTicks end_time_; | 312 base::TimeTicks end_time_; |
301 List<ProfileNode*> samples_; | 313 List<ProfileNode*> samples_; |
302 List<base::TimeTicks> timestamps_; | 314 List<base::TimeTicks> timestamps_; |
303 ProfileTree top_down_; | 315 ProfileTree top_down_; |
304 CpuProfiler* const profiler_; | 316 CpuProfiler* const profiler_; |
| 317 int streaming_next_sample_; |
305 | 318 |
306 DISALLOW_COPY_AND_ASSIGN(CpuProfile); | 319 DISALLOW_COPY_AND_ASSIGN(CpuProfile); |
307 }; | 320 }; |
308 | 321 |
309 class CodeMap { | 322 class CodeMap { |
310 public: | 323 public: |
311 CodeMap() {} | 324 CodeMap() {} |
312 | 325 |
313 void AddCode(Address addr, CodeEntry* entry, unsigned size); | 326 void AddCode(Address addr, CodeEntry* entry, unsigned size); |
314 void MoveCode(Address from, Address to); | 327 void MoveCode(Address from, Address to); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 CodeMap code_map_; | 392 CodeMap code_map_; |
380 | 393 |
381 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); | 394 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); |
382 }; | 395 }; |
383 | 396 |
384 | 397 |
385 } // namespace internal | 398 } // namespace internal |
386 } // namespace v8 | 399 } // namespace v8 |
387 | 400 |
388 #endif // V8_PROFILER_PROFILE_GENERATOR_H_ | 401 #endif // V8_PROFILER_PROFILE_GENERATOR_H_ |
OLD | NEW |