| 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 |