OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 generator_(generator), | 51 generator_(generator), |
52 profiles_(profiles), | 52 profiles_(profiles), |
53 running_(true), | 53 running_(true), |
54 ticks_buffer_(sizeof(TickSampleEventRecord), | 54 ticks_buffer_(sizeof(TickSampleEventRecord), |
55 kTickSamplesBufferChunkSize, | 55 kTickSamplesBufferChunkSize, |
56 kTickSamplesBufferChunksCount), | 56 kTickSamplesBufferChunksCount), |
57 enqueue_order_(0) { | 57 enqueue_order_(0) { |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag, | 61 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { |
62 const char* prefix, | 62 event.generic.order = ++enqueue_order_; |
63 Name* name, | 63 events_buffer_.Enqueue(event); |
64 Address start) { | |
65 if (FilterOutCodeCreateEvent(tag)) return; | |
66 CodeEventsContainer evt_rec; | |
67 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
68 rec->type = CodeEventRecord::CODE_CREATION; | |
69 rec->order = ++enqueue_order_; | |
70 rec->start = start; | |
71 rec->entry = profiles_->NewCodeEntry(tag, prefix, name); | |
72 rec->size = 1; | |
73 rec->shared = NULL; | |
74 events_buffer_.Enqueue(evt_rec); | |
75 } | 64 } |
76 | 65 |
77 | 66 |
78 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
79 Name* name, | |
80 String* resource_name, | |
81 int line_number, | |
82 Address start, | |
83 unsigned size, | |
84 Address shared, | |
85 CompilationInfo* info) { | |
86 if (FilterOutCodeCreateEvent(tag)) return; | |
87 CodeEventsContainer evt_rec; | |
88 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
89 rec->type = CodeEventRecord::CODE_CREATION; | |
90 rec->order = ++enqueue_order_; | |
91 rec->start = start; | |
92 rec->entry = profiles_->NewCodeEntry(tag, name, resource_name, line_number); | |
93 if (info) { | |
94 rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); | |
95 } | |
96 rec->size = size; | |
97 rec->shared = shared; | |
98 events_buffer_.Enqueue(evt_rec); | |
99 } | |
100 | |
101 | |
102 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
103 const char* name, | |
104 Address start, | |
105 unsigned size) { | |
106 if (FilterOutCodeCreateEvent(tag)) return; | |
107 CodeEventsContainer evt_rec; | |
108 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
109 rec->type = CodeEventRecord::CODE_CREATION; | |
110 rec->order = ++enqueue_order_; | |
111 rec->start = start; | |
112 rec->entry = profiles_->NewCodeEntry(tag, name); | |
113 rec->size = size; | |
114 rec->shared = NULL; | |
115 events_buffer_.Enqueue(evt_rec); | |
116 } | |
117 | |
118 | |
119 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
120 int args_count, | |
121 Address start, | |
122 unsigned size) { | |
123 if (FilterOutCodeCreateEvent(tag)) return; | |
124 CodeEventsContainer evt_rec; | |
125 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
126 rec->type = CodeEventRecord::CODE_CREATION; | |
127 rec->order = ++enqueue_order_; | |
128 rec->start = start; | |
129 rec->entry = profiles_->NewCodeEntry(tag, args_count); | |
130 rec->size = size; | |
131 rec->shared = NULL; | |
132 events_buffer_.Enqueue(evt_rec); | |
133 } | |
134 | |
135 | |
136 void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) { | |
137 CodeEventsContainer evt_rec; | |
138 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; | |
139 rec->type = CodeEventRecord::CODE_MOVE; | |
140 rec->order = ++enqueue_order_; | |
141 rec->from = from; | |
142 rec->to = to; | |
143 events_buffer_.Enqueue(evt_rec); | |
144 } | |
145 | |
146 | |
147 void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from, | |
148 Address to) { | |
149 CodeEventsContainer evt_rec; | |
150 SharedFunctionInfoMoveEventRecord* rec = | |
151 &evt_rec.SharedFunctionInfoMoveEventRecord_; | |
152 rec->type = CodeEventRecord::SHARED_FUNC_MOVE; | |
153 rec->order = ++enqueue_order_; | |
154 rec->from = from; | |
155 rec->to = to; | |
156 events_buffer_.Enqueue(evt_rec); | |
157 } | |
158 | |
159 | |
160 void ProfilerEventsProcessor::RegExpCodeCreateEvent( | |
161 Logger::LogEventsAndTags tag, | |
162 const char* prefix, | |
163 String* name, | |
164 Address start, | |
165 unsigned size) { | |
166 if (FilterOutCodeCreateEvent(tag)) return; | |
167 CodeEventsContainer evt_rec; | |
168 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
169 rec->type = CodeEventRecord::CODE_CREATION; | |
170 rec->order = ++enqueue_order_; | |
171 rec->start = start; | |
172 rec->entry = profiles_->NewCodeEntry(tag, prefix, name); | |
173 rec->size = size; | |
174 events_buffer_.Enqueue(evt_rec); | |
175 } | |
176 | |
177 | |
178 void ProfilerEventsProcessor::AddCurrentStack() { | 67 void ProfilerEventsProcessor::AddCurrentStack() { |
179 TickSampleEventRecord record(enqueue_order_); | 68 TickSampleEventRecord record(enqueue_order_); |
180 TickSample* sample = &record.sample; | 69 TickSample* sample = &record.sample; |
181 Isolate* isolate = Isolate::Current(); | 70 Isolate* isolate = Isolate::Current(); |
182 sample->state = isolate->current_vm_state(); | 71 sample->state = isolate->current_vm_state(); |
183 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. | 72 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. |
184 for (StackTraceFrameIterator it(isolate); | 73 for (StackTraceFrameIterator it(isolate); |
185 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; | 74 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; |
186 it.Advance()) { | 75 it.Advance()) { |
187 sample->stack[sample->frames_count++] = it.frame()->pc(); | 76 sample->stack[sample->frames_count++] = it.frame()->pc(); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 profiles_->RemoveProfile(profile); | 187 profiles_->RemoveProfile(profile); |
299 delete profile; | 188 delete profile; |
300 } | 189 } |
301 | 190 |
302 | 191 |
303 bool CpuProfiler::HasDetachedProfiles() { | 192 bool CpuProfiler::HasDetachedProfiles() { |
304 return profiles_->HasDetachedProfiles(); | 193 return profiles_->HasDetachedProfiles(); |
305 } | 194 } |
306 | 195 |
307 | 196 |
| 197 static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag) { |
| 198 return FLAG_prof_browser_mode |
| 199 && (tag != Logger::CALLBACK_TAG |
| 200 && tag != Logger::FUNCTION_TAG |
| 201 && tag != Logger::LAZY_COMPILE_TAG |
| 202 && tag != Logger::REG_EXP_TAG |
| 203 && tag != Logger::SCRIPT_TAG); |
| 204 } |
| 205 |
| 206 |
308 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { | 207 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { |
309 processor_->CallbackCreateEvent( | 208 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; |
310 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); | 209 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 210 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 211 rec->start = entry_point; |
| 212 rec->entry = profiles_->NewCodeEntry( |
| 213 Logger::CALLBACK_TAG, |
| 214 profiles_->GetName(name), |
| 215 TokenEnumerator::kInheritsSecurityToken); |
| 216 rec->size = 1; |
| 217 rec->shared = NULL; |
| 218 processor_->Enqueue(evt_rec); |
311 } | 219 } |
312 | 220 |
313 | 221 |
314 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 222 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
315 Code* code, const char* comment) { | 223 Code* code, |
316 processor_->CodeCreateEvent( | 224 const char* name) { |
317 tag, comment, code->address(), code->ExecutableSize()); | 225 if (FilterOutCodeCreateEvent(tag)) return; |
| 226 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 227 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 228 rec->start = code->address(); |
| 229 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); |
| 230 rec->size = code->ExecutableSize(); |
| 231 rec->shared = NULL; |
| 232 processor_->Enqueue(evt_rec); |
318 } | 233 } |
319 | 234 |
320 | 235 |
321 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 236 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
322 Code* code, Name* name) { | 237 Code* code, |
323 processor_->CodeCreateEvent( | 238 Name* name) { |
324 tag, | 239 if (FilterOutCodeCreateEvent(tag)) return; |
325 name, | 240 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
326 isolate_->heap()->empty_string(), | 241 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
327 v8::CpuProfileNode::kNoLineNumberInfo, | 242 rec->start = code->address(); |
328 code->address(), | 243 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); |
329 code->ExecutableSize(), | 244 rec->size = code->ExecutableSize(); |
330 NULL, | 245 rec->shared = NULL; |
331 NULL); | 246 processor_->Enqueue(evt_rec); |
332 } | 247 } |
333 | 248 |
334 | 249 |
335 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 250 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
336 Code* code, | 251 Code* code, |
337 SharedFunctionInfo* shared, | 252 SharedFunctionInfo* shared, |
338 CompilationInfo* info, | 253 CompilationInfo* info, |
339 Name* name) { | 254 Name* name) { |
340 processor_->CodeCreateEvent( | 255 if (FilterOutCodeCreateEvent(tag)) return; |
341 tag, | 256 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
342 name, | 257 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
343 isolate_->heap()->empty_string(), | 258 rec->start = code->address(); |
344 v8::CpuProfileNode::kNoLineNumberInfo, | 259 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); |
345 code->address(), | 260 rec->entry->set_no_frame_ranges(info ? |
346 code->ExecutableSize(), | 261 info->ReleaseNoFrameRanges() : |
347 shared->address(), | 262 NULL); |
348 info); | 263 rec->size = code->ExecutableSize(); |
| 264 rec->shared = shared->address(); |
| 265 processor_->Enqueue(evt_rec); |
349 } | 266 } |
350 | 267 |
351 | 268 |
352 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 269 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
353 Code* code, | 270 Code* code, |
354 SharedFunctionInfo* shared, | 271 SharedFunctionInfo* shared, |
355 CompilationInfo* info, | 272 CompilationInfo* info, |
356 String* source, int line) { | 273 String* source, int line) { |
357 processor_->CodeCreateEvent( | 274 if (FilterOutCodeCreateEvent(tag)) return; |
| 275 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 276 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 277 rec->start = code->address(); |
| 278 rec->entry = profiles_->NewCodeEntry( |
358 tag, | 279 tag, |
359 shared->DebugName(), | 280 profiles_->GetFunctionName(shared->DebugName()), |
360 source, | 281 TokenEnumerator::kNoSecurityToken, |
361 line, | 282 CodeEntry::kEmptyNamePrefix, |
362 code->address(), | 283 profiles_->GetName(source), |
363 code->ExecutableSize(), | 284 line); |
364 shared->address(), | 285 rec->entry->set_no_frame_ranges(info ? |
365 info); | 286 info->ReleaseNoFrameRanges() : |
| 287 NULL); |
| 288 rec->size = code->ExecutableSize(); |
| 289 rec->shared = shared->address(); |
| 290 processor_->Enqueue(evt_rec); |
366 } | 291 } |
367 | 292 |
368 | 293 |
369 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 294 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
370 Code* code, int args_count) { | 295 Code* code, |
371 processor_->CodeCreateEvent( | 296 int args_count) { |
| 297 if (FilterOutCodeCreateEvent(tag)) return; |
| 298 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 299 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 300 rec->start = code->address(); |
| 301 rec->entry = profiles_->NewCodeEntry( |
372 tag, | 302 tag, |
373 args_count, | 303 profiles_->GetName(args_count), |
374 code->address(), | 304 TokenEnumerator::kInheritsSecurityToken, |
375 code->ExecutableSize()); | 305 "args_count: "); |
| 306 rec->size = code->ExecutableSize(); |
| 307 rec->shared = NULL; |
| 308 processor_->Enqueue(evt_rec); |
376 } | 309 } |
377 | 310 |
378 | 311 |
379 void CpuProfiler::CodeMoveEvent(Address from, Address to) { | 312 void CpuProfiler::CodeMoveEvent(Address from, Address to) { |
380 processor_->CodeMoveEvent(from, to); | 313 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); |
| 314 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; |
| 315 rec->from = from; |
| 316 rec->to = to; |
| 317 processor_->Enqueue(evt_rec); |
381 } | 318 } |
382 | 319 |
383 | 320 |
384 void CpuProfiler::CodeDeleteEvent(Address from) { | 321 void CpuProfiler::CodeDeleteEvent(Address from) { |
385 } | 322 } |
386 | 323 |
387 | 324 |
388 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { | 325 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { |
389 processor_->SharedFunctionInfoMoveEvent(from, to); | 326 CodeEventsContainer evt_rec(CodeEventRecord::SHARED_FUNC_MOVE); |
| 327 SharedFunctionInfoMoveEventRecord* rec = |
| 328 &evt_rec.SharedFunctionInfoMoveEventRecord_; |
| 329 rec->from = from; |
| 330 rec->to = to; |
| 331 processor_->Enqueue(evt_rec); |
390 } | 332 } |
391 | 333 |
392 | 334 |
393 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { | 335 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { |
394 processor_->CallbackCreateEvent( | 336 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; |
395 Logger::CALLBACK_TAG, "get ", name, entry_point); | 337 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 338 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 339 rec->start = entry_point; |
| 340 rec->entry = profiles_->NewCodeEntry( |
| 341 Logger::CALLBACK_TAG, |
| 342 profiles_->GetName(name), |
| 343 TokenEnumerator::kInheritsSecurityToken, |
| 344 "get "); |
| 345 rec->size = 1; |
| 346 rec->shared = NULL; |
| 347 processor_->Enqueue(evt_rec); |
396 } | 348 } |
397 | 349 |
398 | 350 |
399 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { | 351 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { |
400 processor_->RegExpCodeCreateEvent( | 352 if (FilterOutCodeCreateEvent(Logger::REG_EXP_TAG)) return; |
| 353 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 354 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 355 rec->start = code->address(); |
| 356 rec->entry = profiles_->NewCodeEntry( |
401 Logger::REG_EXP_TAG, | 357 Logger::REG_EXP_TAG, |
402 "RegExp: ", | 358 profiles_->GetName(source), |
403 source, | 359 TokenEnumerator::kInheritsSecurityToken, |
404 code->address(), | 360 "RegExp: "); |
405 code->ExecutableSize()); | 361 rec->size = code->ExecutableSize(); |
| 362 processor_->Enqueue(evt_rec); |
406 } | 363 } |
407 | 364 |
408 | 365 |
409 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { | 366 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { |
410 processor_->CallbackCreateEvent( | 367 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; |
411 Logger::CALLBACK_TAG, "set ", name, entry_point); | 368 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 369 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 370 rec->start = entry_point; |
| 371 rec->entry = profiles_->NewCodeEntry( |
| 372 Logger::CALLBACK_TAG, |
| 373 profiles_->GetName(name), |
| 374 TokenEnumerator::kInheritsSecurityToken, |
| 375 "set "); |
| 376 rec->size = 1; |
| 377 rec->shared = NULL; |
| 378 processor_->Enqueue(evt_rec); |
412 } | 379 } |
413 | 380 |
414 | 381 |
415 CpuProfiler::CpuProfiler(Isolate* isolate) | 382 CpuProfiler::CpuProfiler(Isolate* isolate) |
416 : isolate_(isolate), | 383 : isolate_(isolate), |
417 profiles_(new CpuProfilesCollection()), | 384 profiles_(new CpuProfilesCollection()), |
418 next_profile_uid_(1), | 385 next_profile_uid_(1), |
419 token_enumerator_(new TokenEnumerator()), | 386 token_enumerator_(new TokenEnumerator()), |
420 generator_(NULL), | 387 generator_(NULL), |
421 processor_(NULL), | 388 processor_(NULL), |
422 need_to_stop_sampler_(false), | 389 need_to_stop_sampler_(false), |
423 is_profiling_(false) { | 390 is_profiling_(false) { |
424 } | 391 } |
425 | 392 |
426 | 393 |
| 394 CpuProfiler::CpuProfiler(Isolate* isolate, |
| 395 CpuProfilesCollection* test_profiles, |
| 396 ProfileGenerator* test_generator, |
| 397 ProfilerEventsProcessor* test_processor) |
| 398 : isolate_(isolate), |
| 399 profiles_(test_profiles), |
| 400 next_profile_uid_(1), |
| 401 token_enumerator_(new TokenEnumerator()), |
| 402 generator_(test_generator), |
| 403 processor_(test_processor), |
| 404 need_to_stop_sampler_(false), |
| 405 is_profiling_(false) { |
| 406 } |
| 407 |
| 408 |
427 CpuProfiler::~CpuProfiler() { | 409 CpuProfiler::~CpuProfiler() { |
428 delete token_enumerator_; | 410 delete token_enumerator_; |
429 delete profiles_; | 411 delete profiles_; |
430 } | 412 } |
431 | 413 |
432 | 414 |
433 void CpuProfiler::ResetProfiles() { | 415 void CpuProfiler::ResetProfiles() { |
434 delete profiles_; | 416 delete profiles_; |
435 profiles_ = new CpuProfilesCollection(); | 417 profiles_ = new CpuProfilesCollection(); |
436 } | 418 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 processor_->Join(); | 501 processor_->Join(); |
520 delete processor_; | 502 delete processor_; |
521 delete generator_; | 503 delete generator_; |
522 processor_ = NULL; | 504 processor_ = NULL; |
523 generator_ = NULL; | 505 generator_ = NULL; |
524 logger->logging_nesting_ = saved_logging_nesting_; | 506 logger->logging_nesting_ = saved_logging_nesting_; |
525 } | 507 } |
526 | 508 |
527 | 509 |
528 } } // namespace v8::internal | 510 } } // namespace v8::internal |
OLD | NEW |