OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 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 17 matching lines...) Expand all Loading... |
28 #ifndef V8_PROFILE_GENERATOR_H_ | 28 #ifndef V8_PROFILE_GENERATOR_H_ |
29 #define V8_PROFILE_GENERATOR_H_ | 29 #define V8_PROFILE_GENERATOR_H_ |
30 | 30 |
31 #ifdef ENABLE_LOGGING_AND_PROFILING | 31 #ifdef ENABLE_LOGGING_AND_PROFILING |
32 | 32 |
33 #include "hashmap.h" | 33 #include "hashmap.h" |
34 | 34 |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
| 38 class TokenEnumerator { |
| 39 public: |
| 40 TokenEnumerator(); |
| 41 ~TokenEnumerator(); |
| 42 int GetTokenId(Object* token); |
| 43 |
| 44 private: |
| 45 static void TokenRemovedCallback(v8::Persistent<v8::Value> handle, |
| 46 void* parameter); |
| 47 void TokenRemoved(Object** token_location); |
| 48 |
| 49 List<Object**> token_locations_; |
| 50 List<bool> token_removed_; |
| 51 |
| 52 friend class TokenEnumeratorTester; |
| 53 }; |
| 54 |
| 55 |
38 class CodeEntry { | 56 class CodeEntry { |
39 public: | 57 public: |
| 58 explicit INLINE(CodeEntry(int security_token_id)); |
40 // CodeEntry doesn't own name strings, just references them. | 59 // CodeEntry doesn't own name strings, just references them. |
41 INLINE(CodeEntry(Logger::LogEventsAndTags tag, | 60 INLINE(CodeEntry(Logger::LogEventsAndTags tag, |
42 const char* name_prefix, | 61 const char* name_prefix, |
43 const char* name, | 62 const char* name, |
44 const char* resource_name, | 63 const char* resource_name, |
45 int line_number)); | 64 int line_number, |
| 65 int security_token_id)); |
46 | 66 |
47 INLINE(bool is_js_function() const) { return is_js_function_tag(tag_); } | 67 INLINE(bool is_js_function() const) { return is_js_function_tag(tag_); } |
48 INLINE(const char* name_prefix() const) { return name_prefix_; } | 68 INLINE(const char* name_prefix() const) { return name_prefix_; } |
49 INLINE(bool has_name_prefix() const) { return name_prefix_[0] != '\0'; } | 69 INLINE(bool has_name_prefix() const) { return name_prefix_[0] != '\0'; } |
50 INLINE(const char* name() const) { return name_; } | 70 INLINE(const char* name() const) { return name_; } |
51 INLINE(const char* resource_name() const) { return resource_name_; } | 71 INLINE(const char* resource_name() const) { return resource_name_; } |
52 INLINE(int line_number() const) { return line_number_; } | 72 INLINE(int line_number() const) { return line_number_; } |
53 INLINE(unsigned call_uid() const) { return call_uid_; } | 73 INLINE(unsigned call_uid() const) { return call_uid_; } |
| 74 INLINE(int security_token_id() const) { return security_token_id_; } |
54 | 75 |
55 INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag)); | 76 INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag)); |
56 | 77 |
| 78 void CopyData(const CodeEntry& source); |
| 79 |
57 static const char* kEmptyNamePrefix; | 80 static const char* kEmptyNamePrefix; |
| 81 static const int kNoSecurityToken = -1; |
| 82 static const int kInheritsSecurityToken = -2; |
58 | 83 |
59 private: | 84 private: |
60 const unsigned call_uid_; | 85 unsigned call_uid_; |
61 Logger::LogEventsAndTags tag_; | 86 Logger::LogEventsAndTags tag_; |
62 const char* name_prefix_; | 87 const char* name_prefix_; |
63 const char* name_; | 88 const char* name_; |
64 const char* resource_name_; | 89 const char* resource_name_; |
65 int line_number_; | 90 int line_number_; |
| 91 int security_token_id_; |
66 | 92 |
67 static unsigned next_call_uid_; | 93 static unsigned next_call_uid_; |
68 | 94 |
69 DISALLOW_COPY_AND_ASSIGN(CodeEntry); | 95 DISALLOW_COPY_AND_ASSIGN(CodeEntry); |
70 }; | 96 }; |
71 | 97 |
72 | 98 |
73 class ProfileTree; | 99 class ProfileTree; |
74 | 100 |
75 class ProfileNode { | 101 class ProfileNode { |
76 public: | 102 public: |
77 INLINE(ProfileNode(ProfileTree* tree, CodeEntry* entry)); | 103 INLINE(ProfileNode(ProfileTree* tree, CodeEntry* entry)); |
78 | 104 |
79 ProfileNode* FindChild(CodeEntry* entry); | 105 ProfileNode* FindChild(CodeEntry* entry); |
80 ProfileNode* FindOrAddChild(CodeEntry* entry); | 106 ProfileNode* FindOrAddChild(CodeEntry* entry); |
81 INLINE(void IncrementSelfTicks()) { ++self_ticks_; } | 107 INLINE(void IncrementSelfTicks()) { ++self_ticks_; } |
| 108 INLINE(void IncreaseSelfTicks(unsigned amount)) { self_ticks_ += amount; } |
82 INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; } | 109 INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; } |
83 | 110 |
84 INLINE(CodeEntry* entry() const) { return entry_; } | 111 INLINE(CodeEntry* entry() const) { return entry_; } |
85 INLINE(unsigned self_ticks() const) { return self_ticks_; } | 112 INLINE(unsigned self_ticks() const) { return self_ticks_; } |
86 INLINE(unsigned total_ticks() const) { return total_ticks_; } | 113 INLINE(unsigned total_ticks() const) { return total_ticks_; } |
87 INLINE(const List<ProfileNode*>* children() const) { return &children_list_; } | 114 INLINE(const List<ProfileNode*>* children() const) { return &children_list_; } |
88 double GetSelfMillis() const; | 115 double GetSelfMillis() const; |
89 double GetTotalMillis() const; | 116 double GetTotalMillis() const; |
90 | 117 |
91 void Print(int indent); | 118 void Print(int indent); |
(...skipping 20 matching lines...) Expand all Loading... |
112 | 139 |
113 | 140 |
114 class ProfileTree { | 141 class ProfileTree { |
115 public: | 142 public: |
116 ProfileTree(); | 143 ProfileTree(); |
117 ~ProfileTree(); | 144 ~ProfileTree(); |
118 | 145 |
119 void AddPathFromEnd(const Vector<CodeEntry*>& path); | 146 void AddPathFromEnd(const Vector<CodeEntry*>& path); |
120 void AddPathFromStart(const Vector<CodeEntry*>& path); | 147 void AddPathFromStart(const Vector<CodeEntry*>& path); |
121 void CalculateTotalTicks(); | 148 void CalculateTotalTicks(); |
| 149 void FilteredClone(ProfileTree* src, int security_token_id); |
122 | 150 |
123 double TicksToMillis(unsigned ticks) const { | 151 double TicksToMillis(unsigned ticks) const { |
124 return ticks * ms_to_ticks_scale_; | 152 return ticks * ms_to_ticks_scale_; |
125 } | 153 } |
126 ProfileNode* root() const { return root_; } | 154 ProfileNode* root() const { return root_; } |
127 void SetTickRatePerMs(double ticks_per_ms); | 155 void SetTickRatePerMs(double ticks_per_ms); |
128 | 156 |
129 void ShortPrint(); | 157 void ShortPrint(); |
130 void Print() { | 158 void Print() { |
131 root_->Print(0); | 159 root_->Print(0); |
132 } | 160 } |
133 | 161 |
134 private: | 162 private: |
135 template <typename Callback> | 163 template <typename Callback> |
136 void TraverseDepthFirstPostOrder(Callback* callback); | 164 void TraverseDepthFirst(Callback* callback); |
137 | 165 |
138 CodeEntry root_entry_; | 166 CodeEntry root_entry_; |
139 ProfileNode* root_; | 167 ProfileNode* root_; |
140 double ms_to_ticks_scale_; | 168 double ms_to_ticks_scale_; |
141 | 169 |
142 DISALLOW_COPY_AND_ASSIGN(ProfileTree); | 170 DISALLOW_COPY_AND_ASSIGN(ProfileTree); |
143 }; | 171 }; |
144 | 172 |
145 | 173 |
146 class CpuProfile { | 174 class CpuProfile { |
147 public: | 175 public: |
148 CpuProfile(const char* title, unsigned uid) | 176 CpuProfile(const char* title, unsigned uid) |
149 : title_(title), uid_(uid) { } | 177 : title_(title), uid_(uid) { } |
150 | 178 |
151 // Add pc -> ... -> main() call path to the profile. | 179 // Add pc -> ... -> main() call path to the profile. |
152 void AddPath(const Vector<CodeEntry*>& path); | 180 void AddPath(const Vector<CodeEntry*>& path); |
153 void CalculateTotalTicks(); | 181 void CalculateTotalTicks(); |
154 void SetActualSamplingRate(double actual_sampling_rate); | 182 void SetActualSamplingRate(double actual_sampling_rate); |
| 183 CpuProfile* FilteredClone(int security_token_id); |
155 | 184 |
156 INLINE(const char* title() const) { return title_; } | 185 INLINE(const char* title() const) { return title_; } |
157 INLINE(unsigned uid() const) { return uid_; } | 186 INLINE(unsigned uid() const) { return uid_; } |
158 INLINE(const ProfileTree* top_down() const) { return &top_down_; } | 187 INLINE(const ProfileTree* top_down() const) { return &top_down_; } |
159 INLINE(const ProfileTree* bottom_up() const) { return &bottom_up_; } | 188 INLINE(const ProfileTree* bottom_up() const) { return &bottom_up_; } |
160 | 189 |
161 void UpdateTicksScale(); | 190 void UpdateTicksScale(); |
162 | 191 |
163 void ShortPrint(); | 192 void ShortPrint(); |
164 void Print(); | 193 void Print(); |
165 | 194 |
166 private: | 195 private: |
167 const char* title_; | 196 const char* title_; |
168 unsigned uid_; | 197 unsigned uid_; |
169 ProfileTree top_down_; | 198 ProfileTree top_down_; |
170 ProfileTree bottom_up_; | 199 ProfileTree bottom_up_; |
171 | 200 |
172 DISALLOW_COPY_AND_ASSIGN(CpuProfile); | 201 DISALLOW_COPY_AND_ASSIGN(CpuProfile); |
173 }; | 202 }; |
174 | 203 |
175 | 204 |
176 class CodeMap { | 205 class CodeMap { |
177 public: | 206 public: |
178 CodeMap() { } | 207 CodeMap() { } |
179 INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size)); | 208 INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size)); |
180 INLINE(void MoveCode(Address from, Address to)); | 209 INLINE(void MoveCode(Address from, Address to)); |
181 INLINE(void DeleteCode(Address addr)); | 210 INLINE(void DeleteCode(Address addr)); |
182 void AddAlias(Address alias, Address addr); | 211 void AddAlias(Address start, CodeEntry* entry, Address code_start); |
183 CodeEntry* FindEntry(Address addr); | 212 CodeEntry* FindEntry(Address addr); |
184 | 213 |
185 void Print(); | 214 void Print(); |
186 | 215 |
187 private: | 216 private: |
188 struct CodeEntryInfo { | 217 struct CodeEntryInfo { |
189 CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) | 218 CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) |
190 : entry(an_entry), size(a_size) { } | 219 : entry(an_entry), size(a_size) { } |
191 CodeEntry* entry; | 220 CodeEntry* entry; |
192 unsigned size; | 221 unsigned size; |
(...skipping 21 matching lines...) Expand all Loading... |
214 }; | 243 }; |
215 | 244 |
216 | 245 |
217 class CpuProfilesCollection { | 246 class CpuProfilesCollection { |
218 public: | 247 public: |
219 CpuProfilesCollection(); | 248 CpuProfilesCollection(); |
220 ~CpuProfilesCollection(); | 249 ~CpuProfilesCollection(); |
221 | 250 |
222 bool StartProfiling(const char* title, unsigned uid); | 251 bool StartProfiling(const char* title, unsigned uid); |
223 bool StartProfiling(String* title, unsigned uid); | 252 bool StartProfiling(String* title, unsigned uid); |
224 CpuProfile* StopProfiling(const char* title, double actual_sampling_rate); | 253 CpuProfile* StopProfiling(int security_token_id, |
225 CpuProfile* StopProfiling(String* title, double actual_sampling_rate); | 254 const char* title, |
226 INLINE(List<CpuProfile*>* profiles()) { return &profiles_; } | 255 double actual_sampling_rate); |
227 CpuProfile* GetProfile(unsigned uid); | 256 CpuProfile* StopProfiling(int security_token_id, |
| 257 String* title, |
| 258 double actual_sampling_rate); |
| 259 List<CpuProfile*>* Profiles(int security_token_id); |
| 260 CpuProfile* GetProfile(int security_token_id, unsigned uid); |
228 inline bool is_last_profile(); | 261 inline bool is_last_profile(); |
229 | 262 |
230 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, | 263 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, |
231 String* name, String* resource_name, int line_number); | 264 String* name, String* resource_name, int line_number); |
232 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name); | 265 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name); |
233 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, | 266 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, |
234 const char* name_prefix, String* name); | 267 const char* name_prefix, String* name); |
235 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count); | 268 CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count); |
| 269 CodeEntry* NewCodeEntry(int security_token_id); |
236 | 270 |
237 // Called from profile generator thread. | 271 // Called from profile generator thread. |
238 void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path); | 272 void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path); |
239 | 273 |
240 private: | 274 private: |
241 INLINE(const char* GetFunctionName(String* name)); | 275 INLINE(const char* GetFunctionName(String* name)); |
242 INLINE(const char* GetFunctionName(const char* name)); | 276 INLINE(const char* GetFunctionName(const char* name)); |
243 const char* GetName(String* name); | 277 const char* GetName(String* name); |
244 const char* GetName(int args_count); | 278 const char* GetName(int args_count); |
| 279 List<CpuProfile*>* GetProfilesList(int security_token_id); |
| 280 int TokenToIndex(int security_token_id); |
245 | 281 |
246 INLINE(static bool StringsMatch(void* key1, void* key2)) { | 282 INLINE(static bool StringsMatch(void* key1, void* key2)) { |
247 return strcmp(reinterpret_cast<char*>(key1), | 283 return strcmp(reinterpret_cast<char*>(key1), |
248 reinterpret_cast<char*>(key2)) == 0; | 284 reinterpret_cast<char*>(key2)) == 0; |
249 } | 285 } |
250 | 286 |
251 INLINE(static bool CpuProfilesMatch(void* key1, void* key2)) { | 287 INLINE(static bool UidsMatch(void* key1, void* key2)) { |
252 return key1 == key2; | 288 return key1 == key2; |
253 } | 289 } |
254 | 290 |
255 // String::Hash -> const char* | 291 // String::Hash -> const char* |
256 HashMap function_and_resource_names_; | 292 HashMap function_and_resource_names_; |
257 // args_count -> char* | 293 // args_count -> char* |
258 List<char*> args_count_names_; | 294 List<char*> args_count_names_; |
259 List<CodeEntry*> code_entries_; | 295 List<CodeEntry*> code_entries_; |
260 List<CpuProfile*> profiles_; | 296 List<List<CpuProfile*>* > profiles_by_token_; |
261 // uid -> CpuProfile* | 297 // uid -> index |
262 HashMap profiles_uids_; | 298 HashMap profiles_uids_; |
263 | 299 |
264 // Accessed by VM thread and profile generator thread. | 300 // Accessed by VM thread and profile generator thread. |
265 List<CpuProfile*> current_profiles_; | 301 List<CpuProfile*> current_profiles_; |
266 Semaphore* current_profiles_semaphore_; | 302 Semaphore* current_profiles_semaphore_; |
267 | 303 |
268 DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); | 304 DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); |
269 }; | 305 }; |
270 | 306 |
271 | 307 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 const char* name_prefix, | 361 const char* name_prefix, |
326 String* name)) { | 362 String* name)) { |
327 return profiles_->NewCodeEntry(tag, name_prefix, name); | 363 return profiles_->NewCodeEntry(tag, name_prefix, name); |
328 } | 364 } |
329 | 365 |
330 INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, | 366 INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, |
331 int args_count)) { | 367 int args_count)) { |
332 return profiles_->NewCodeEntry(tag, args_count); | 368 return profiles_->NewCodeEntry(tag, args_count); |
333 } | 369 } |
334 | 370 |
| 371 INLINE(CodeEntry* NewCodeEntry(int security_token_id)) { |
| 372 return profiles_->NewCodeEntry(security_token_id); |
| 373 } |
| 374 |
335 void RecordTickSample(const TickSample& sample); | 375 void RecordTickSample(const TickSample& sample); |
336 | 376 |
337 INLINE(CodeMap* code_map()) { return &code_map_; } | 377 INLINE(CodeMap* code_map()) { return &code_map_; } |
338 | 378 |
339 INLINE(void Tick()) { sample_rate_calc_.Tick(); } | 379 INLINE(void Tick()) { sample_rate_calc_.Tick(); } |
340 INLINE(double actual_sampling_rate()) { | 380 INLINE(double actual_sampling_rate()) { |
341 return sample_rate_calc_.ticks_per_ms(); | 381 return sample_rate_calc_.ticks_per_ms(); |
342 } | 382 } |
343 | 383 |
344 static const char* kAnonymousFunctionName; | 384 static const char* kAnonymousFunctionName; |
(...skipping 10 matching lines...) Expand all Loading... |
355 SampleRateCalculator sample_rate_calc_; | 395 SampleRateCalculator sample_rate_calc_; |
356 | 396 |
357 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); | 397 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); |
358 }; | 398 }; |
359 | 399 |
360 } } // namespace v8::internal | 400 } } // namespace v8::internal |
361 | 401 |
362 #endif // ENABLE_LOGGING_AND_PROFILING | 402 #endif // ENABLE_LOGGING_AND_PROFILING |
363 | 403 |
364 #endif // V8_PROFILE_GENERATOR_H_ | 404 #endif // V8_PROFILE_GENERATOR_H_ |
OLD | NEW |