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

Side by Side Diff: src/cpu-profiler.cc

Issue 6551011: Fix CPU profiling for Crankshaft. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 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 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 static const int kTickSamplesBufferChunksCount = 16; 46 static const int kTickSamplesBufferChunksCount = 16;
47 47
48 48
49 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator) 49 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
50 : Thread("v8:ProfEvntProc"), 50 : Thread("v8:ProfEvntProc"),
51 generator_(generator), 51 generator_(generator),
52 running_(true), 52 running_(true),
53 ticks_buffer_(sizeof(TickSampleEventRecord), 53 ticks_buffer_(sizeof(TickSampleEventRecord),
54 kTickSamplesBufferChunkSize, 54 kTickSamplesBufferChunkSize,
55 kTickSamplesBufferChunksCount), 55 kTickSamplesBufferChunksCount),
56 enqueue_order_(0), 56 enqueue_order_(0) {
57 known_functions_(new HashMap(AddressesMatch)) {
58 } 57 }
59 58
60 59
61 ProfilerEventsProcessor::~ProfilerEventsProcessor() {
62 delete known_functions_;
63 }
64
65
66 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag, 60 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
67 const char* prefix, 61 const char* prefix,
68 String* name, 62 String* name,
69 Address start) { 63 Address start) {
70 if (FilterOutCodeCreateEvent(tag)) return; 64 if (FilterOutCodeCreateEvent(tag)) return;
71 CodeEventsContainer evt_rec; 65 CodeEventsContainer evt_rec;
72 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 66 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
73 rec->type = CodeEventRecord::CODE_CREATION; 67 rec->type = CodeEventRecord::CODE_CREATION;
74 rec->order = ++enqueue_order_; 68 rec->order = ++enqueue_order_;
75 rec->start = start; 69 rec->start = start;
76 rec->entry = generator_->NewCodeEntry(tag, prefix, name); 70 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
77 rec->size = 1; 71 rec->size = 1;
72 rec->sfi_address = NULL;
78 events_buffer_.Enqueue(evt_rec); 73 events_buffer_.Enqueue(evt_rec);
79 } 74 }
80 75
81 76
82 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, 77 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
83 String* name, 78 String* name,
84 String* resource_name, 79 String* resource_name,
85 int line_number, 80 int line_number,
86 Address start, 81 Address start,
87 unsigned size) { 82 unsigned size,
83 Address sfi_address) {
88 if (FilterOutCodeCreateEvent(tag)) return; 84 if (FilterOutCodeCreateEvent(tag)) return;
89 CodeEventsContainer evt_rec; 85 CodeEventsContainer evt_rec;
90 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 86 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
91 rec->type = CodeEventRecord::CODE_CREATION; 87 rec->type = CodeEventRecord::CODE_CREATION;
92 rec->order = ++enqueue_order_; 88 rec->order = ++enqueue_order_;
93 rec->start = start; 89 rec->start = start;
94 rec->entry = generator_->NewCodeEntry(tag, name, resource_name, line_number); 90 rec->entry = generator_->NewCodeEntry(tag, name, resource_name, line_number);
95 rec->size = size; 91 rec->size = size;
92 rec->sfi_address = sfi_address;
96 events_buffer_.Enqueue(evt_rec); 93 events_buffer_.Enqueue(evt_rec);
97 } 94 }
98 95
99 96
100 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, 97 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
101 const char* name, 98 const char* name,
102 Address start, 99 Address start,
103 unsigned size) { 100 unsigned size) {
104 if (FilterOutCodeCreateEvent(tag)) return; 101 if (FilterOutCodeCreateEvent(tag)) return;
105 CodeEventsContainer evt_rec; 102 CodeEventsContainer evt_rec;
106 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 103 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
107 rec->type = CodeEventRecord::CODE_CREATION; 104 rec->type = CodeEventRecord::CODE_CREATION;
108 rec->order = ++enqueue_order_; 105 rec->order = ++enqueue_order_;
109 rec->start = start; 106 rec->start = start;
110 rec->entry = generator_->NewCodeEntry(tag, name); 107 rec->entry = generator_->NewCodeEntry(tag, name);
111 rec->size = size; 108 rec->size = size;
109 rec->sfi_address = NULL;
112 events_buffer_.Enqueue(evt_rec); 110 events_buffer_.Enqueue(evt_rec);
113 } 111 }
114 112
115 113
116 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, 114 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
117 int args_count, 115 int args_count,
118 Address start, 116 Address start,
119 unsigned size) { 117 unsigned size) {
120 if (FilterOutCodeCreateEvent(tag)) return; 118 if (FilterOutCodeCreateEvent(tag)) return;
121 CodeEventsContainer evt_rec; 119 CodeEventsContainer evt_rec;
122 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 120 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
123 rec->type = CodeEventRecord::CODE_CREATION; 121 rec->type = CodeEventRecord::CODE_CREATION;
124 rec->order = ++enqueue_order_; 122 rec->order = ++enqueue_order_;
125 rec->start = start; 123 rec->start = start;
126 rec->entry = generator_->NewCodeEntry(tag, args_count); 124 rec->entry = generator_->NewCodeEntry(tag, args_count);
127 rec->size = size; 125 rec->size = size;
126 rec->sfi_address = NULL;
128 events_buffer_.Enqueue(evt_rec); 127 events_buffer_.Enqueue(evt_rec);
129 } 128 }
130 129
131 130
132 void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) { 131 void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
133 CodeEventsContainer evt_rec; 132 CodeEventsContainer evt_rec;
134 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; 133 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
135 rec->type = CodeEventRecord::CODE_MOVE; 134 rec->type = CodeEventRecord::CODE_MOVE;
136 rec->order = ++enqueue_order_; 135 rec->order = ++enqueue_order_;
137 rec->from = from; 136 rec->from = from;
138 rec->to = to; 137 rec->to = to;
139 events_buffer_.Enqueue(evt_rec); 138 events_buffer_.Enqueue(evt_rec);
140 } 139 }
141 140
142 141
143 void ProfilerEventsProcessor::CodeDeleteEvent(Address from) { 142 void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
144 CodeEventsContainer evt_rec; 143 CodeEventsContainer evt_rec;
145 CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_; 144 CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
146 rec->type = CodeEventRecord::CODE_DELETE; 145 rec->type = CodeEventRecord::CODE_DELETE;
147 rec->order = ++enqueue_order_; 146 rec->order = ++enqueue_order_;
148 rec->start = from; 147 rec->start = from;
149 events_buffer_.Enqueue(evt_rec); 148 events_buffer_.Enqueue(evt_rec);
150 } 149 }
151 150
152 151
153 void ProfilerEventsProcessor::FunctionCreateEvent(Address alias, 152 void ProfilerEventsProcessor::SFIMoveEvent(Address from, Address to) {
154 Address start,
155 int security_token_id) {
156 CodeEventsContainer evt_rec; 153 CodeEventsContainer evt_rec;
157 CodeAliasEventRecord* rec = &evt_rec.CodeAliasEventRecord_; 154 SFIMoveEventRecord* rec = &evt_rec.SFIMoveEventRecord_;
158 rec->type = CodeEventRecord::CODE_ALIAS; 155 rec->type = CodeEventRecord::SFI_MOVE;
159 rec->order = ++enqueue_order_; 156 rec->order = ++enqueue_order_;
160 rec->start = alias; 157 rec->from = from;
161 rec->entry = generator_->NewCodeEntry(security_token_id); 158 rec->to = to;
162 rec->code_start = start;
163 events_buffer_.Enqueue(evt_rec); 159 events_buffer_.Enqueue(evt_rec);
164
165 known_functions_->Lookup(alias, AddressHash(alias), true);
166 } 160 }
167 161
168 162
169 void ProfilerEventsProcessor::FunctionMoveEvent(Address from, Address to) {
170 CodeMoveEvent(from, to);
171
172 if (IsKnownFunction(from)) {
173 known_functions_->Remove(from, AddressHash(from));
174 known_functions_->Lookup(to, AddressHash(to), true);
175 }
176 }
177
178
179 void ProfilerEventsProcessor::FunctionDeleteEvent(Address from) {
180 CodeDeleteEvent(from);
181
182 known_functions_->Remove(from, AddressHash(from));
183 }
184
185
186 bool ProfilerEventsProcessor::IsKnownFunction(Address start) {
187 HashMap::Entry* entry =
188 known_functions_->Lookup(start, AddressHash(start), false);
189 return entry != NULL;
190 }
191
192
193 void ProfilerEventsProcessor::ProcessMovedFunctions() {
194 for (int i = 0; i < moved_functions_.length(); ++i) {
195 JSFunction* function = moved_functions_[i];
196 CpuProfiler::FunctionCreateEvent(function);
197 }
198 moved_functions_.Clear();
199 }
200
201
202 void ProfilerEventsProcessor::RememberMovedFunction(JSFunction* function) {
203 moved_functions_.Add(function);
204 }
205
206
207 void ProfilerEventsProcessor::RegExpCodeCreateEvent( 163 void ProfilerEventsProcessor::RegExpCodeCreateEvent(
208 Logger::LogEventsAndTags tag, 164 Logger::LogEventsAndTags tag,
209 const char* prefix, 165 const char* prefix,
210 String* name, 166 String* name,
211 Address start, 167 Address start,
212 unsigned size) { 168 unsigned size) {
213 if (FilterOutCodeCreateEvent(tag)) return; 169 if (FilterOutCodeCreateEvent(tag)) return;
214 CodeEventsContainer evt_rec; 170 CodeEventsContainer evt_rec;
215 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 171 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
216 rec->type = CodeEventRecord::CODE_CREATION; 172 rec->type = CodeEventRecord::CODE_CREATION;
217 rec->order = ++enqueue_order_; 173 rec->order = ++enqueue_order_;
218 rec->start = start; 174 rec->start = start;
219 rec->entry = generator_->NewCodeEntry(tag, prefix, name); 175 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
220 rec->size = size; 176 rec->size = size;
221 events_buffer_.Enqueue(evt_rec); 177 events_buffer_.Enqueue(evt_rec);
222 } 178 }
223 179
224 180
225 void ProfilerEventsProcessor::AddCurrentStack() { 181 void ProfilerEventsProcessor::AddCurrentStack() {
226 TickSampleEventRecord record; 182 TickSampleEventRecord record;
227 TickSample* sample = &record.sample; 183 TickSample* sample = &record.sample;
228 sample->state = Top::current_vm_state(); 184 sample->state = Top::current_vm_state();
229 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. 185 sample->pc = reinterpret_cast<Address>(sample); // Not NULL.
186 sample->function = NULL;
230 sample->frames_count = 0; 187 sample->frames_count = 0;
231 for (StackTraceFrameIterator it; 188 for (StackTraceFrameIterator it;
232 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; 189 !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
233 it.Advance()) { 190 it.Advance()) {
234 JavaScriptFrame* frame = it.frame(); 191 sample->stack[sample->frames_count++] = it.frame()->pc();
235 sample->stack[sample->frames_count++] =
236 reinterpret_cast<Address>(frame->function());
237 } 192 }
238 record.order = enqueue_order_; 193 record.order = enqueue_order_;
239 ticks_from_vm_buffer_.Enqueue(record); 194 ticks_from_vm_buffer_.Enqueue(record);
240 } 195 }
241 196
242 197
243 bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) { 198 bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) {
244 if (!events_buffer_.IsEmpty()) { 199 if (!events_buffer_.IsEmpty()) {
245 CodeEventsContainer record; 200 CodeEventsContainer record;
246 events_buffer_.Dequeue(&record); 201 events_buffer_.Dequeue(&record);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 341
387 342
388 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 343 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
389 Code* code, String* name) { 344 Code* code, String* name) {
390 singleton_->processor_->CodeCreateEvent( 345 singleton_->processor_->CodeCreateEvent(
391 tag, 346 tag,
392 name, 347 name,
393 Heap::empty_string(), 348 Heap::empty_string(),
394 v8::CpuProfileNode::kNoLineNumberInfo, 349 v8::CpuProfileNode::kNoLineNumberInfo,
395 code->address(), 350 code->address(),
396 code->ExecutableSize()); 351 code->ExecutableSize(),
352 NULL);
397 } 353 }
398 354
399 355
400 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 356 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
401 Code* code, String* name, 357 Code* code,
402 String* source, int line) { 358 SharedFunctionInfo *shared,
Vitaly Repeshko 2011/02/22 15:11:19 nit: Move *.
mnaganov (inactive) 2011/02/22 16:18:22 Done.
359 String* name) {
403 singleton_->processor_->CodeCreateEvent( 360 singleton_->processor_->CodeCreateEvent(
404 tag, 361 tag,
405 name, 362 name,
363 Heap::empty_string(),
364 v8::CpuProfileNode::kNoLineNumberInfo,
365 code->address(),
366 code->ExecutableSize(),
367 shared->address());
368 }
369
370
371 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
372 Code* code,
373 SharedFunctionInfo *shared,
Vitaly Repeshko 2011/02/22 15:11:19 Same nit.
mnaganov (inactive) 2011/02/22 16:18:22 Done.
374 String* source, int line) {
375 singleton_->processor_->CodeCreateEvent(
376 tag,
377 shared->DebugName(),
406 source, 378 source,
407 line, 379 line,
408 code->address(), 380 code->address(),
409 code->ExecutableSize()); 381 code->ExecutableSize(),
382 shared->address());
410 } 383 }
411 384
412 385
413 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 386 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
414 Code* code, int args_count) { 387 Code* code, int args_count) {
415 singleton_->processor_->CodeCreateEvent( 388 singleton_->processor_->CodeCreateEvent(
416 tag, 389 tag,
417 args_count, 390 args_count,
418 code->address(), 391 code->address(),
419 code->ExecutableSize()); 392 code->ExecutableSize());
420 } 393 }
421 394
422 395
423 void CpuProfiler::CodeMoveEvent(Address from, Address to) { 396 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
424 singleton_->processor_->CodeMoveEvent(from, to); 397 singleton_->processor_->CodeMoveEvent(from, to);
425 } 398 }
426 399
427 400
428 void CpuProfiler::CodeDeleteEvent(Address from) { 401 void CpuProfiler::CodeDeleteEvent(Address from) {
429 singleton_->processor_->CodeDeleteEvent(from); 402 singleton_->processor_->CodeDeleteEvent(from);
430 } 403 }
431 404
432 405
433 void CpuProfiler::FunctionCreateEvent(JSFunction* function) { 406 void CpuProfiler::SFIMoveEvent(Address from, Address to) {
434 int security_token_id = TokenEnumerator::kNoSecurityToken; 407 singleton_->processor_->SFIMoveEvent(from, to);
435 if (function->unchecked_context()->IsContext()) {
436 security_token_id = singleton_->token_enumerator_->GetTokenId(
437 function->context()->global_context()->security_token());
438 }
439 singleton_->processor_->FunctionCreateEvent(
440 function->address(),
441 function->shared()->code()->address(),
442 security_token_id);
443 } 408 }
444 409
445 410
446 void CpuProfiler::ProcessMovedFunctions() {
447 singleton_->processor_->ProcessMovedFunctions();
448 }
449
450
451 void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function) {
452 // This function is called from GC iterators (during Scavenge,
453 // MC, and MS), so marking bits can be set on objects. That's
454 // why unchecked accessors are used here.
455
456 // The same function can be reported several times.
457 if (function->unchecked_code() == Builtins::builtin(Builtins::LazyCompile)
458 || singleton_->processor_->IsKnownFunction(function->address())) return;
459
460 singleton_->processor_->RememberMovedFunction(function);
461 }
462
463
464 void CpuProfiler::FunctionMoveEvent(Address from, Address to) {
465 singleton_->processor_->FunctionMoveEvent(from, to);
466 }
467
468
469 void CpuProfiler::FunctionDeleteEvent(Address from) {
470 singleton_->processor_->FunctionDeleteEvent(from);
471 }
472
473
474 void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) { 411 void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
475 singleton_->processor_->CallbackCreateEvent( 412 singleton_->processor_->CallbackCreateEvent(
476 Logger::CALLBACK_TAG, "get ", name, entry_point); 413 Logger::CALLBACK_TAG, "get ", name, entry_point);
477 } 414 }
478 415
479 416
480 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { 417 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
481 singleton_->processor_->RegExpCodeCreateEvent( 418 singleton_->processor_->RegExpCodeCreateEvent(
482 Logger::REG_EXP_TAG, 419 Logger::REG_EXP_TAG,
483 "RegExp: ", 420 "RegExp: ",
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 processor_->Start(); 469 processor_->Start();
533 // Enumerate stuff we already have in the heap. 470 // Enumerate stuff we already have in the heap.
534 if (Heap::HasBeenSetup()) { 471 if (Heap::HasBeenSetup()) {
535 if (!FLAG_prof_browser_mode) { 472 if (!FLAG_prof_browser_mode) {
536 bool saved_log_code_flag = FLAG_log_code; 473 bool saved_log_code_flag = FLAG_log_code;
537 FLAG_log_code = true; 474 FLAG_log_code = true;
538 Logger::LogCodeObjects(); 475 Logger::LogCodeObjects();
539 FLAG_log_code = saved_log_code_flag; 476 FLAG_log_code = saved_log_code_flag;
540 } 477 }
541 Logger::LogCompiledFunctions(); 478 Logger::LogCompiledFunctions();
542 Logger::LogFunctionObjects();
543 Logger::LogAccessorCallbacks(); 479 Logger::LogAccessorCallbacks();
544 } 480 }
545 // Enable stack sampling. 481 // Enable stack sampling.
546 Sampler* sampler = reinterpret_cast<Sampler*>(Logger::ticker_); 482 Sampler* sampler = reinterpret_cast<Sampler*>(Logger::ticker_);
547 if (!sampler->IsActive()) sampler->Start(); 483 if (!sampler->IsActive()) sampler->Start();
548 sampler->IncreaseProfilingDepth(); 484 sampler->IncreaseProfilingDepth();
549 } 485 }
550 } 486 }
551 487
552 488
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 void CpuProfiler::TearDown() { 545 void CpuProfiler::TearDown() {
610 #ifdef ENABLE_LOGGING_AND_PROFILING 546 #ifdef ENABLE_LOGGING_AND_PROFILING
611 if (singleton_ != NULL) { 547 if (singleton_ != NULL) {
612 delete singleton_; 548 delete singleton_;
613 } 549 }
614 singleton_ = NULL; 550 singleton_ = NULL;
615 #endif 551 #endif
616 } 552 }
617 553
618 } } // namespace v8::internal 554 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698