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

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

Issue 148503002: A64: Synchronize with r15545. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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
« no previous file with comments | « src/cpu-profiler.h ('k') | src/cpu-profiler-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 27 matching lines...) Expand all
38 #include "../include/v8-profiler.h" 38 #include "../include/v8-profiler.h"
39 39
40 namespace v8 { 40 namespace v8 {
41 namespace internal { 41 namespace internal {
42 42
43 static const int kTickSamplesBufferChunkSize = 64 * KB; 43 static const int kTickSamplesBufferChunkSize = 64 * KB;
44 static const int kTickSamplesBufferChunksCount = 16; 44 static const int kTickSamplesBufferChunksCount = 16;
45 static const int kProfilerStackSize = 64 * KB; 45 static const int kProfilerStackSize = 64 * KB;
46 46
47 47
48 ProfilerEventsProcessor::ProfilerEventsProcessor( 48 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
49 ProfileGenerator* generator, CpuProfilesCollection* profiles)
50 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), 49 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
51 generator_(generator), 50 generator_(generator),
52 profiles_(profiles),
53 running_(true), 51 running_(true),
54 ticks_buffer_(sizeof(TickSampleEventRecord), 52 ticks_buffer_(sizeof(TickSampleEventRecord),
55 kTickSamplesBufferChunkSize, 53 kTickSamplesBufferChunkSize,
56 kTickSamplesBufferChunksCount), 54 kTickSamplesBufferChunksCount),
57 enqueue_order_(0) { 55 last_code_event_id_(0), last_processed_code_event_id_(0) {
58 } 56 }
59 57
60 58
61 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag, 59 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
62 const char* prefix, 60 event.generic.order = ++last_code_event_id_;
63 Name* name, 61 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 } 62 }
76 63
77 64
78 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, 65 void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate) {
79 Name* name, 66 TickSampleEventRecord record(last_code_event_id_);
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() {
179 TickSampleEventRecord record(enqueue_order_);
180 TickSample* sample = &record.sample; 67 TickSample* sample = &record.sample;
181 Isolate* isolate = Isolate::Current();
182 sample->state = isolate->current_vm_state(); 68 sample->state = isolate->current_vm_state();
183 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. 69 sample->pc = reinterpret_cast<Address>(sample); // Not NULL.
184 for (StackTraceFrameIterator it(isolate); 70 for (StackTraceFrameIterator it(isolate);
185 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; 71 !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
186 it.Advance()) { 72 it.Advance()) {
187 sample->stack[sample->frames_count++] = it.frame()->pc(); 73 sample->stack[sample->frames_count++] = it.frame()->pc();
188 } 74 }
189 ticks_from_vm_buffer_.Enqueue(record); 75 ticks_from_vm_buffer_.Enqueue(record);
190 } 76 }
191 77
192 78
193 bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) { 79 void ProfilerEventsProcessor::StopSynchronously() {
80 if (!running_) return;
81 running_ = false;
82 Join();
83 }
84
85
86 bool ProfilerEventsProcessor::ProcessCodeEvent() {
194 CodeEventsContainer record; 87 CodeEventsContainer record;
195 if (events_buffer_.Dequeue(&record)) { 88 if (events_buffer_.Dequeue(&record)) {
196 switch (record.generic.type) { 89 switch (record.generic.type) {
197 #define PROFILER_TYPE_CASE(type, clss) \ 90 #define PROFILER_TYPE_CASE(type, clss) \
198 case CodeEventRecord::type: \ 91 case CodeEventRecord::type: \
199 record.clss##_.UpdateCodeMap(generator_->code_map()); \ 92 record.clss##_.UpdateCodeMap(generator_->code_map()); \
200 break; 93 break;
201 94
202 CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE) 95 CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE)
203 96
204 #undef PROFILER_TYPE_CASE 97 #undef PROFILER_TYPE_CASE
205 default: return true; // Skip record. 98 default: return true; // Skip record.
206 } 99 }
207 *dequeue_order = record.generic.order; 100 last_processed_code_event_id_ = record.generic.order;
208 return true; 101 return true;
209 } 102 }
210 return false; 103 return false;
211 } 104 }
212 105
213 106
214 bool ProfilerEventsProcessor::ProcessTicks(unsigned dequeue_order) { 107 bool ProfilerEventsProcessor::ProcessTicks() {
215 while (true) { 108 while (true) {
216 if (!ticks_from_vm_buffer_.IsEmpty() 109 if (!ticks_from_vm_buffer_.IsEmpty()
217 && ticks_from_vm_buffer_.Peek()->order == dequeue_order) { 110 && ticks_from_vm_buffer_.Peek()->order ==
111 last_processed_code_event_id_) {
218 TickSampleEventRecord record; 112 TickSampleEventRecord record;
219 ticks_from_vm_buffer_.Dequeue(&record); 113 ticks_from_vm_buffer_.Dequeue(&record);
220 generator_->RecordTickSample(record.sample); 114 generator_->RecordTickSample(record.sample);
221 } 115 }
222 116
223 const TickSampleEventRecord* rec = 117 const TickSampleEventRecord* rec =
224 TickSampleEventRecord::cast(ticks_buffer_.StartDequeue()); 118 TickSampleEventRecord::cast(ticks_buffer_.StartDequeue());
225 if (rec == NULL) return !ticks_from_vm_buffer_.IsEmpty(); 119 if (rec == NULL) return !ticks_from_vm_buffer_.IsEmpty();
226 // Make a local copy of tick sample record to ensure that it won't 120 // Make a local copy of tick sample record to ensure that it won't
227 // be modified as we are processing it. This is possible as the 121 // be modified as we are processing it. This is possible as the
228 // sampler writes w/o any sync to the queue, so if the processor 122 // sampler writes w/o any sync to the queue, so if the processor
229 // will get far behind, a record may be modified right under its 123 // will get far behind, a record may be modified right under its
230 // feet. 124 // feet.
231 TickSampleEventRecord record = *rec; 125 TickSampleEventRecord record = *rec;
232 if (record.order == dequeue_order) { 126 if (record.order != last_processed_code_event_id_) return true;
233 // A paranoid check to make sure that we don't get a memory overrun 127
234 // in case of frames_count having a wild value. 128 // A paranoid check to make sure that we don't get a memory overrun
235 if (record.sample.frames_count < 0 129 // in case of frames_count having a wild value.
236 || record.sample.frames_count > TickSample::kMaxFramesCount) 130 if (record.sample.frames_count < 0
237 record.sample.frames_count = 0; 131 || record.sample.frames_count > TickSample::kMaxFramesCount)
238 generator_->RecordTickSample(record.sample); 132 record.sample.frames_count = 0;
239 ticks_buffer_.FinishDequeue(); 133 generator_->RecordTickSample(record.sample);
240 } else { 134 ticks_buffer_.FinishDequeue();
241 return true;
242 }
243 } 135 }
244 } 136 }
245 137
246 138
247 void ProfilerEventsProcessor::Run() { 139 void ProfilerEventsProcessor::Run() {
248 unsigned dequeue_order = 0;
249
250 while (running_) { 140 while (running_) {
251 // Process ticks until we have any. 141 // Process ticks until we have any.
252 if (ProcessTicks(dequeue_order)) { 142 if (ProcessTicks()) {
253 // All ticks of the current dequeue_order are processed, 143 // All ticks of the current last_processed_code_event_id_ are processed,
254 // proceed to the next code event. 144 // proceed to the next code event.
255 ProcessCodeEvent(&dequeue_order); 145 ProcessCodeEvent();
256 } 146 }
257 YieldCPU(); 147 YieldCPU();
258 } 148 }
259 149
260 // Process remaining tick events. 150 // Process remaining tick events.
261 ticks_buffer_.FlushResidualRecords(); 151 ticks_buffer_.FlushResidualRecords();
262 // Perform processing until we have tick events, skip remaining code events. 152 do {
263 while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { } 153 ProcessTicks();
154 } while (ProcessCodeEvent());
264 } 155 }
265 156
266 157
267 int CpuProfiler::GetProfilesCount() { 158 int CpuProfiler::GetProfilesCount() {
268 // The count of profiles doesn't depend on a security token. 159 // The count of profiles doesn't depend on a security token.
269 return profiles_->Profiles(TokenEnumerator::kNoSecurityToken)->length(); 160 return profiles_->profiles()->length();
270 } 161 }
271 162
272 163
273 CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) { 164 CpuProfile* CpuProfiler::GetProfile(int index) {
274 const int token = token_enumerator_->GetTokenId(security_token); 165 return profiles_->profiles()->at(index);
275 return profiles_->Profiles(token)->at(index);
276 } 166 }
277 167
278 168
279 CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
280 const int token = token_enumerator_->GetTokenId(security_token);
281 return profiles_->GetProfile(token, uid);
282 }
283
284
285 TickSample* CpuProfiler::TickSampleEvent() { 169 TickSample* CpuProfiler::TickSampleEvent() {
286 if (is_profiling_) return processor_->TickSampleEvent(); 170 if (is_profiling_) return processor_->TickSampleEvent();
287 return NULL; 171 return NULL;
288 } 172 }
289 173
290 174
291 void CpuProfiler::DeleteAllProfiles() { 175 void CpuProfiler::DeleteAllProfiles() {
292 if (is_profiling_) StopProcessor(); 176 if (is_profiling_) StopProcessor();
293 ResetProfiles(); 177 ResetProfiles();
294 } 178 }
295 179
296 180
297 void CpuProfiler::DeleteProfile(CpuProfile* profile) { 181 void CpuProfiler::DeleteProfile(CpuProfile* profile) {
298 profiles_->RemoveProfile(profile); 182 profiles_->RemoveProfile(profile);
299 delete profile; 183 delete profile;
300 } 184 }
301 185
302 186
303 bool CpuProfiler::HasDetachedProfiles() { 187 static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag) {
304 return profiles_->HasDetachedProfiles(); 188 return FLAG_prof_browser_mode
189 && (tag != Logger::CALLBACK_TAG
190 && tag != Logger::FUNCTION_TAG
191 && tag != Logger::LAZY_COMPILE_TAG
192 && tag != Logger::REG_EXP_TAG
193 && tag != Logger::SCRIPT_TAG);
305 } 194 }
306 195
307 196
308 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { 197 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) {
309 processor_->CallbackCreateEvent( 198 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
310 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); 199 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
200 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
201 rec->start = entry_point;
202 rec->entry = profiles_->NewCodeEntry(
203 Logger::CALLBACK_TAG,
204 profiles_->GetName(name));
205 rec->size = 1;
206 rec->shared = NULL;
207 processor_->Enqueue(evt_rec);
311 } 208 }
312 209
313 210
314 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 211 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
315 Code* code, const char* comment) { 212 Code* code,
316 processor_->CodeCreateEvent( 213 const char* name) {
317 tag, comment, code->address(), code->ExecutableSize()); 214 if (FilterOutCodeCreateEvent(tag)) return;
215 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
216 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
217 rec->start = code->address();
218 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
219 rec->size = code->ExecutableSize();
220 rec->shared = NULL;
221 processor_->Enqueue(evt_rec);
318 } 222 }
319 223
320 224
321 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 225 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
322 Code* code, Name* name) { 226 Code* code,
323 processor_->CodeCreateEvent( 227 Name* name) {
324 tag, 228 if (FilterOutCodeCreateEvent(tag)) return;
325 name, 229 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
326 isolate_->heap()->empty_string(), 230 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
327 v8::CpuProfileNode::kNoLineNumberInfo, 231 rec->start = code->address();
328 code->address(), 232 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
329 code->ExecutableSize(), 233 rec->size = code->ExecutableSize();
330 NULL, 234 rec->shared = NULL;
331 NULL); 235 processor_->Enqueue(evt_rec);
332 } 236 }
333 237
334 238
335 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 239 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
336 Code* code, 240 Code* code,
337 SharedFunctionInfo* shared, 241 SharedFunctionInfo* shared,
338 CompilationInfo* info, 242 CompilationInfo* info,
339 Name* name) { 243 Name* name) {
340 processor_->CodeCreateEvent( 244 if (FilterOutCodeCreateEvent(tag)) return;
341 tag, 245 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
342 name, 246 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
343 isolate_->heap()->empty_string(), 247 rec->start = code->address();
344 v8::CpuProfileNode::kNoLineNumberInfo, 248 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
345 code->address(), 249 if (info) {
346 code->ExecutableSize(), 250 rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
347 shared->address(), 251 }
348 info); 252 if (shared->script()->IsScript()) {
253 ASSERT(Script::cast(shared->script()));
254 Script* script = Script::cast(shared->script());
255 rec->entry->set_script_id(script->id()->value());
256 }
257 rec->size = code->ExecutableSize();
258 rec->shared = shared->address();
259 processor_->Enqueue(evt_rec);
349 } 260 }
350 261
351 262
352 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 263 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
353 Code* code, 264 Code* code,
354 SharedFunctionInfo* shared, 265 SharedFunctionInfo* shared,
355 CompilationInfo* info, 266 CompilationInfo* info,
356 String* source, int line) { 267 String* source, int line) {
357 processor_->CodeCreateEvent( 268 if (FilterOutCodeCreateEvent(tag)) return;
269 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
270 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
271 rec->start = code->address();
272 rec->entry = profiles_->NewCodeEntry(
358 tag, 273 tag,
359 shared->DebugName(), 274 profiles_->GetFunctionName(shared->DebugName()),
360 source, 275 CodeEntry::kEmptyNamePrefix,
361 line, 276 profiles_->GetName(source),
362 code->address(), 277 line);
363 code->ExecutableSize(), 278 if (info) {
364 shared->address(), 279 rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
365 info); 280 }
281 ASSERT(Script::cast(shared->script()));
282 Script* script = Script::cast(shared->script());
283 rec->entry->set_script_id(script->id()->value());
284 rec->size = code->ExecutableSize();
285 rec->shared = shared->address();
286 processor_->Enqueue(evt_rec);
366 } 287 }
367 288
368 289
369 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 290 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
370 Code* code, int args_count) { 291 Code* code,
371 processor_->CodeCreateEvent( 292 int args_count) {
293 if (FilterOutCodeCreateEvent(tag)) return;
294 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
295 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
296 rec->start = code->address();
297 rec->entry = profiles_->NewCodeEntry(
372 tag, 298 tag,
373 args_count, 299 profiles_->GetName(args_count),
374 code->address(), 300 "args_count: ");
375 code->ExecutableSize()); 301 rec->size = code->ExecutableSize();
302 rec->shared = NULL;
303 processor_->Enqueue(evt_rec);
376 } 304 }
377 305
378 306
379 void CpuProfiler::CodeMoveEvent(Address from, Address to) { 307 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
380 processor_->CodeMoveEvent(from, to); 308 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
309 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
310 rec->from = from;
311 rec->to = to;
312 processor_->Enqueue(evt_rec);
381 } 313 }
382 314
383 315
384 void CpuProfiler::CodeDeleteEvent(Address from) { 316 void CpuProfiler::CodeDeleteEvent(Address from) {
385 } 317 }
386 318
387 319
388 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { 320 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
389 processor_->SharedFunctionInfoMoveEvent(from, to); 321 CodeEventsContainer evt_rec(CodeEventRecord::SHARED_FUNC_MOVE);
322 SharedFunctionInfoMoveEventRecord* rec =
323 &evt_rec.SharedFunctionInfoMoveEventRecord_;
324 rec->from = from;
325 rec->to = to;
326 processor_->Enqueue(evt_rec);
390 } 327 }
391 328
392 329
393 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { 330 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
394 processor_->CallbackCreateEvent( 331 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
395 Logger::CALLBACK_TAG, "get ", name, entry_point); 332 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
333 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
334 rec->start = entry_point;
335 rec->entry = profiles_->NewCodeEntry(
336 Logger::CALLBACK_TAG,
337 profiles_->GetName(name),
338 "get ");
339 rec->size = 1;
340 rec->shared = NULL;
341 processor_->Enqueue(evt_rec);
396 } 342 }
397 343
398 344
399 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { 345 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
400 processor_->RegExpCodeCreateEvent( 346 if (FilterOutCodeCreateEvent(Logger::REG_EXP_TAG)) return;
347 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
348 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
349 rec->start = code->address();
350 rec->entry = profiles_->NewCodeEntry(
401 Logger::REG_EXP_TAG, 351 Logger::REG_EXP_TAG,
402 "RegExp: ", 352 profiles_->GetName(source),
403 source, 353 "RegExp: ");
404 code->address(), 354 rec->size = code->ExecutableSize();
405 code->ExecutableSize()); 355 processor_->Enqueue(evt_rec);
406 } 356 }
407 357
408 358
409 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { 359 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
410 processor_->CallbackCreateEvent( 360 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return;
411 Logger::CALLBACK_TAG, "set ", name, entry_point); 361 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
362 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
363 rec->start = entry_point;
364 rec->entry = profiles_->NewCodeEntry(
365 Logger::CALLBACK_TAG,
366 profiles_->GetName(name),
367 "set ");
368 rec->size = 1;
369 rec->shared = NULL;
370 processor_->Enqueue(evt_rec);
412 } 371 }
413 372
414 373
415 CpuProfiler::CpuProfiler(Isolate* isolate) 374 CpuProfiler::CpuProfiler(Isolate* isolate)
416 : isolate_(isolate), 375 : isolate_(isolate),
417 profiles_(new CpuProfilesCollection()), 376 profiles_(new CpuProfilesCollection()),
418 next_profile_uid_(1), 377 next_profile_uid_(1),
419 token_enumerator_(new TokenEnumerator()),
420 generator_(NULL), 378 generator_(NULL),
421 processor_(NULL), 379 processor_(NULL),
422 need_to_stop_sampler_(false), 380 need_to_stop_sampler_(false),
423 is_profiling_(false) { 381 is_profiling_(false) {
424 } 382 }
425 383
426 384
385 CpuProfiler::CpuProfiler(Isolate* isolate,
386 CpuProfilesCollection* test_profiles,
387 ProfileGenerator* test_generator,
388 ProfilerEventsProcessor* test_processor)
389 : isolate_(isolate),
390 profiles_(test_profiles),
391 next_profile_uid_(1),
392 generator_(test_generator),
393 processor_(test_processor),
394 need_to_stop_sampler_(false),
395 is_profiling_(false) {
396 }
397
398
427 CpuProfiler::~CpuProfiler() { 399 CpuProfiler::~CpuProfiler() {
428 delete token_enumerator_; 400 ASSERT(!is_profiling_);
429 delete profiles_; 401 delete profiles_;
430 } 402 }
431 403
432 404
433 void CpuProfiler::ResetProfiles() { 405 void CpuProfiler::ResetProfiles() {
434 delete profiles_; 406 delete profiles_;
435 profiles_ = new CpuProfilesCollection(); 407 profiles_ = new CpuProfilesCollection();
436 } 408 }
437 409
410
438 void CpuProfiler::StartProfiling(const char* title, bool record_samples) { 411 void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
439 if (profiles_->StartProfiling(title, next_profile_uid_++, record_samples)) { 412 if (profiles_->StartProfiling(title, next_profile_uid_++, record_samples)) {
440 StartProcessorIfNotStarted(); 413 StartProcessorIfNotStarted();
441 } 414 }
442 processor_->AddCurrentStack(); 415 processor_->AddCurrentStack(isolate_);
443 } 416 }
444 417
445 418
446 void CpuProfiler::StartProfiling(String* title, bool record_samples) { 419 void CpuProfiler::StartProfiling(String* title, bool record_samples) {
447 StartProfiling(profiles_->GetName(title), record_samples); 420 StartProfiling(profiles_->GetName(title), record_samples);
448 } 421 }
449 422
450 423
451 void CpuProfiler::StartProcessorIfNotStarted() { 424 void CpuProfiler::StartProcessorIfNotStarted() {
452 if (processor_ == NULL) { 425 if (processor_ == NULL) {
426 Logger* logger = isolate_->logger();
453 // Disable logging when using the new implementation. 427 // Disable logging when using the new implementation.
454 saved_logging_nesting_ = isolate_->logger()->logging_nesting_; 428 saved_logging_nesting_ = logger->logging_nesting_;
455 isolate_->logger()->logging_nesting_ = 0; 429 logger->logging_nesting_ = 0;
456 generator_ = new ProfileGenerator(profiles_); 430 generator_ = new ProfileGenerator(profiles_);
457 processor_ = new ProfilerEventsProcessor(generator_, profiles_); 431 processor_ = new ProfilerEventsProcessor(generator_);
458 is_profiling_ = true; 432 is_profiling_ = true;
459 processor_->StartSynchronously(); 433 processor_->StartSynchronously();
460 // Enumerate stuff we already have in the heap. 434 // Enumerate stuff we already have in the heap.
461 if (isolate_->heap()->HasBeenSetUp()) { 435 ASSERT(isolate_->heap()->HasBeenSetUp());
462 if (!FLAG_prof_browser_mode) { 436 if (!FLAG_prof_browser_mode) {
463 isolate_->logger()->LogCodeObjects(); 437 logger->LogCodeObjects();
464 }
465 isolate_->logger()->LogCompiledFunctions();
466 isolate_->logger()->LogAccessorCallbacks();
467 } 438 }
439 logger->LogCompiledFunctions();
440 logger->LogAccessorCallbacks();
441 LogBuiltins();
468 // Enable stack sampling. 442 // Enable stack sampling.
469 Sampler* sampler = isolate_->logger()->sampler(); 443 Sampler* sampler = logger->sampler();
470 sampler->IncreaseProfilingDepth(); 444 sampler->IncreaseProfilingDepth();
471 if (!sampler->IsActive()) { 445 if (!sampler->IsActive()) {
472 sampler->Start(); 446 sampler->Start();
473 need_to_stop_sampler_ = true; 447 need_to_stop_sampler_ = true;
474 } 448 }
475 } 449 }
476 } 450 }
477 451
478 452
479 CpuProfile* CpuProfiler::StopProfiling(const char* title) { 453 CpuProfile* CpuProfiler::StopProfiling(const char* title) {
480 if (!is_profiling_) return NULL; 454 if (!is_profiling_) return NULL;
481 const double actual_sampling_rate = generator_->actual_sampling_rate(); 455 const double actual_sampling_rate = generator_->actual_sampling_rate();
482 StopProcessorIfLastProfile(title); 456 StopProcessorIfLastProfile(title);
483 CpuProfile* result = 457 CpuProfile* result = profiles_->StopProfiling(title, actual_sampling_rate);
484 profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken,
485 title,
486 actual_sampling_rate);
487 if (result != NULL) { 458 if (result != NULL) {
488 result->Print(); 459 result->Print();
489 } 460 }
490 return result; 461 return result;
491 } 462 }
492 463
493 464
494 CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) { 465 CpuProfile* CpuProfiler::StopProfiling(String* title) {
495 if (!is_profiling_) return NULL; 466 if (!is_profiling_) return NULL;
496 const double actual_sampling_rate = generator_->actual_sampling_rate(); 467 const double actual_sampling_rate = generator_->actual_sampling_rate();
497 const char* profile_title = profiles_->GetName(title); 468 const char* profile_title = profiles_->GetName(title);
498 StopProcessorIfLastProfile(profile_title); 469 StopProcessorIfLastProfile(profile_title);
499 int token = token_enumerator_->GetTokenId(security_token); 470 return profiles_->StopProfiling(profile_title, actual_sampling_rate);
500 return profiles_->StopProfiling(token, profile_title, actual_sampling_rate);
501 } 471 }
502 472
503 473
504 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { 474 void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
505 if (profiles_->IsLastProfile(title)) StopProcessor(); 475 if (profiles_->IsLastProfile(title)) StopProcessor();
506 } 476 }
507 477
508 478
509 void CpuProfiler::StopProcessor() { 479 void CpuProfiler::StopProcessor() {
510 Logger* logger = isolate_->logger(); 480 Logger* logger = isolate_->logger();
511 Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_); 481 Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
512 sampler->DecreaseProfilingDepth(); 482 sampler->DecreaseProfilingDepth();
513 if (need_to_stop_sampler_) { 483 if (need_to_stop_sampler_) {
514 sampler->Stop(); 484 sampler->Stop();
515 need_to_stop_sampler_ = false; 485 need_to_stop_sampler_ = false;
516 } 486 }
517 is_profiling_ = false; 487 is_profiling_ = false;
518 processor_->Stop(); 488 processor_->StopSynchronously();
519 processor_->Join();
520 delete processor_; 489 delete processor_;
521 delete generator_; 490 delete generator_;
522 processor_ = NULL; 491 processor_ = NULL;
523 generator_ = NULL; 492 generator_ = NULL;
524 logger->logging_nesting_ = saved_logging_nesting_; 493 logger->logging_nesting_ = saved_logging_nesting_;
525 } 494 }
526 495
527 496
497 void CpuProfiler::LogBuiltins() {
498 Builtins* builtins = isolate_->builtins();
499 ASSERT(builtins->is_initialized());
500 for (int i = 0; i < Builtins::builtin_count; i++) {
501 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
502 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
503 Builtins::Name id = static_cast<Builtins::Name>(i);
504 rec->start = builtins->builtin(id)->address();
505 rec->builtin_id = id;
506 processor_->Enqueue(evt_rec);
507 }
508 }
509
510
528 } } // namespace v8::internal 511 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/cpu-profiler.h ('k') | src/cpu-profiler-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698