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

Side by Side Diff: runtime/vm/timeline_analysis.cc

Issue 1287073006: Correct inclusive time and start tracking maximum exclusive time (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « runtime/vm/timeline_analysis.h ('k') | runtime/vm/timeline_test.cc » ('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 (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/timeline_analysis.h" 5 #include "vm/timeline_analysis.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/log.h" 8 #include "vm/log.h"
9 #include "vm/os_thread.h" 9 #include "vm/os_thread.h"
10 10
(...skipping 20 matching lines...) Expand all
31 ASSERT(a != NULL); 31 ASSERT(a != NULL);
32 ASSERT(*a != NULL); 32 ASSERT(*a != NULL);
33 ASSERT(b != NULL); 33 ASSERT(b != NULL);
34 ASSERT(*b != NULL); 34 ASSERT(*b != NULL);
35 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); 35 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
36 } 36 }
37 37
38 38
39 void TimelineAnalysisThread::Finalize() { 39 void TimelineAnalysisThread::Finalize() {
40 blocks_.Sort(CompareBlocksLowerTimeBound); 40 blocks_.Sort(CompareBlocksLowerTimeBound);
41 ISL_Print("Thread %" Px " has %" Pd " blocks\n", 41 if (FLAG_trace_timeline_analysis) {
42 OSThread::ThreadIdToIntPtr(id_), 42 ISL_Print("Thread %" Px " has %" Pd " blocks\n",
43 blocks_.length()); 43 OSThread::ThreadIdToIntPtr(id_),
44 blocks_.length());
45 }
44 } 46 }
45 47
46 48
47 TimelineAnalysisThreadEventIterator::TimelineAnalysisThreadEventIterator( 49 TimelineAnalysisThreadEventIterator::TimelineAnalysisThreadEventIterator(
48 TimelineAnalysisThread* thread) { 50 TimelineAnalysisThread* thread) {
49 Reset(thread); 51 Reset(thread);
50 } 52 }
51 53
52 54
53 TimelineAnalysisThreadEventIterator::~TimelineAnalysisThreadEventIterator() { 55 TimelineAnalysisThreadEventIterator::~TimelineAnalysisThreadEventIterator() {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 va_start(args, format); 194 va_start(args, format);
193 error_msg_ = zone_->VPrint(format, args); 195 error_msg_ = zone_->VPrint(format, args);
194 ASSERT(error_msg_ != NULL); 196 ASSERT(error_msg_ != NULL);
195 } 197 }
196 198
197 199
198 TimelineLabelPauseInfo::TimelineLabelPauseInfo(const char* name) 200 TimelineLabelPauseInfo::TimelineLabelPauseInfo(const char* name)
199 : name_(name), 201 : name_(name),
200 inclusive_micros_(0), 202 inclusive_micros_(0),
201 exclusive_micros_(0), 203 exclusive_micros_(0),
202 max_duration_micros_(0) { 204 max_inclusive_micros_(0),
205 max_exclusive_micros_(0) {
203 ASSERT(name_ != NULL); 206 ASSERT(name_ != NULL);
204 } 207 }
205 208
206 209
207 void TimelineLabelPauseInfo::OnPush(int64_t micros) { 210 void TimelineLabelPauseInfo::OnPush(int64_t micros, bool already_on_stack) {
208 add_inclusive_micros(micros); 211 if (!already_on_stack) {
209 add_exclusive_micros(micros); 212 // Only adjust inclusive counts if we aren't already on the stack.
210 if (micros > max_duration_micros_) { 213 add_inclusive_micros(micros);
211 max_duration_micros_ = micros; 214 if (micros > max_inclusive_micros_) {
215 max_inclusive_micros_ = micros;
216 }
212 } 217 }
213 } 218 }
214 219
215 220
216 void TimelineLabelPauseInfo::OnChildPush(int64_t micros) { 221 void TimelineLabelPauseInfo::OnPop(int64_t exclusive_micros) {
217 ASSERT(micros >= 0); 222 add_exclusive_micros(exclusive_micros);
218 add_exclusive_micros(-micros); 223 if (exclusive_micros > max_exclusive_micros_) {
224 max_exclusive_micros_ = exclusive_micros;
225 }
219 } 226 }
220 227
221 228
222 TimelinePauses::TimelinePauses(Zone* zone, 229 TimelinePauses::TimelinePauses(Zone* zone,
223 Isolate* isolate, 230 Isolate* isolate,
224 TimelineEventRecorder* recorder) 231 TimelineEventRecorder* recorder)
225 : TimelineAnalysis(zone, isolate, recorder) { 232 : TimelineAnalysis(zone, isolate, recorder) {
226 } 233 }
227 234
228 235
229 void TimelinePauses::Setup() { 236 void TimelinePauses::Setup() {
230 BuildThreads(); 237 BuildThreads();
231 } 238 }
232 239
233 240
234 void TimelinePauses::CalculatePauseTimesForThread(ThreadId tid) { 241 void TimelinePauses::CalculatePauseTimesForThread(ThreadId tid) {
235 if (has_error()) { 242 if (has_error()) {
236 return; 243 return;
237 } 244 }
238 TimelineAnalysisThread* thread = GetThread(tid); 245 TimelineAnalysisThread* thread = GetThread(tid);
239 if (thread == NULL) { 246 if (thread == NULL) {
240 SetError("Thread %" Px " does not exist.", OSThread::ThreadIdToIntPtr(tid)); 247 SetError("Thread %" Px " does not exist.", OSThread::ThreadIdToIntPtr(tid));
241 return; 248 return;
242 } 249 }
243 ProcessThread(thread); 250 ProcessThread(thread);
244 } 251 }
245 252
246 253
247 TimelineLabelPauseInfo* TimelinePauses::GetLabel(const char* name) const { 254 TimelineLabelPauseInfo* TimelinePauses::GetLabelPauseInfo(
255 const char* name) const {
248 ASSERT(name != NULL); 256 ASSERT(name != NULL);
249 // Linear lookup because we expect N (# of labels in an isolate) to be small. 257 // Linear lookup because we expect N (# of labels in an isolate) to be small.
250 for (intptr_t i = 0; i < labels_.length(); i++) { 258 for (intptr_t i = 0; i < labels_.length(); i++) {
251 TimelineLabelPauseInfo* label = labels_.At(i); 259 TimelineLabelPauseInfo* label = labels_.At(i);
252 if (strcmp(label->name(), name) == 0) { 260 if (strcmp(label->name(), name) == 0) {
253 return label; 261 return label;
254 } 262 }
255 } 263 }
256 return NULL; 264 return NULL;
257 } 265 }
258 266
259 267
260 int64_t TimelinePauses::InclusiveTime(const char* name) const { 268 int64_t TimelinePauses::InclusiveTime(const char* name) const {
261 TimelineLabelPauseInfo* pause_info = GetLabel(name); 269 TimelineLabelPauseInfo* pause_info = GetLabelPauseInfo(name);
262 ASSERT(pause_info != NULL); 270 ASSERT(pause_info != NULL);
263 return pause_info->inclusive_micros(); 271 return pause_info->inclusive_micros();
264 } 272 }
265 273
266 274
267 int64_t TimelinePauses::ExclusiveTime(const char* name) const { 275 int64_t TimelinePauses::ExclusiveTime(const char* name) const {
268 TimelineLabelPauseInfo* pause_info = GetLabel(name); 276 TimelineLabelPauseInfo* pause_info = GetLabelPauseInfo(name);
269 ASSERT(pause_info != NULL); 277 ASSERT(pause_info != NULL);
270 return pause_info->exclusive_micros(); 278 return pause_info->exclusive_micros();
271 } 279 }
272 280
273 281
274 int64_t TimelinePauses::MaxDurationTime(const char* name) const { 282 int64_t TimelinePauses::MaxInclusiveTime(const char* name) const {
275 TimelineLabelPauseInfo* pause_info = GetLabel(name); 283 TimelineLabelPauseInfo* pause_info = GetLabelPauseInfo(name);
276 ASSERT(pause_info != NULL); 284 ASSERT(pause_info != NULL);
277 return pause_info->max_duration_micros(); 285 return pause_info->max_inclusive_micros();
278 } 286 }
279 287
280 288
289 int64_t TimelinePauses::MaxExclusiveTime(const char* name) const {
290 TimelineLabelPauseInfo* pause_info = GetLabelPauseInfo(name);
291 ASSERT(pause_info != NULL);
292 return pause_info->max_exclusive_micros();
293 }
294
295
281 void TimelinePauses::ProcessThread(TimelineAnalysisThread* thread) { 296 void TimelinePauses::ProcessThread(TimelineAnalysisThread* thread) {
282 ASSERT(thread != NULL); 297 ASSERT(thread != NULL);
283 stack_.Clear(); 298 stack_.Clear();
284 labels_.Clear(); 299 labels_.Clear();
285 300
286 TimelineAnalysisThreadEventIterator it(thread); 301 TimelineAnalysisThreadEventIterator it(thread);
287 if (FLAG_trace_timeline_analysis) { 302 if (FLAG_trace_timeline_analysis) {
288 ISL_Print(">>> TimelinePauses::ProcessThread %" Px "\n", 303 ISL_Print(">>> TimelinePauses::ProcessThread %" Px "\n",
289 OSThread::ThreadIdToIntPtr(thread->id())); 304 OSThread::ThreadIdToIntPtr(thread->id()));
290 } 305 }
(...skipping 20 matching lines...) Expand all
311 OSThread::ThreadIdToIntPtr(thread->id()), 326 OSThread::ThreadIdToIntPtr(thread->id()),
312 event_count); 327 event_count);
313 } 328 }
314 } 329 }
315 330
316 331
317 // Verify that |event| is contained within all parent events on the stack. 332 // Verify that |event| is contained within all parent events on the stack.
318 bool TimelinePauses::CheckStack(TimelineEvent* event) { 333 bool TimelinePauses::CheckStack(TimelineEvent* event) {
319 ASSERT(event != NULL); 334 ASSERT(event != NULL);
320 for (intptr_t i = 0; i < stack_.length(); i++) { 335 for (intptr_t i = 0; i < stack_.length(); i++) {
321 TimelineEvent* slot = stack_.At(i); 336 const StackItem& slot = stack_.At(i);
322 if (!slot->DurationContains(event)) { 337 if (!slot.event->DurationContains(event)) {
323 return false; 338 return false;
324 } 339 }
325 } 340 }
326 return true; 341 return true;
327 } 342 }
328 343
329 344
330 void TimelinePauses::PopFinished(int64_t start) { 345 void TimelinePauses::PopFinished(int64_t start) {
331 while (stack_.length() > 0) { 346 while (stack_.length() > 0) {
332 TimelineEvent* top = stack_.Last(); 347 const StackItem& top = stack_.Last();
333 if (top->DurationFinishedBefore(start)) { 348 if (top.event->DurationFinishedBefore(start)) {
349 top.pause_info->OnPop(top.exclusive_micros);
334 // Top of stack completes before |start|. 350 // Top of stack completes before |start|.
335 stack_.RemoveLast(); 351 stack_.RemoveLast();
336 if (FLAG_trace_timeline_analysis) { 352 if (FLAG_trace_timeline_analysis) {
337 ISL_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n", 353 ISL_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n",
338 top->label(), 354 top.event->label(),
339 top->TimeEnd(), 355 top.event->TimeEnd(),
340 start); 356 start);
341 } 357 }
342 } else { 358 } else {
343 return; 359 return;
344 } 360 }
345 } 361 }
346 } 362 }
347 363
348 364
349 void TimelinePauses::Push(TimelineEvent* event) { 365 void TimelinePauses::Push(TimelineEvent* event) {
350 TimelineLabelPauseInfo* pause_info = GetOrAddLabel(event->label()); 366 TimelineLabelPauseInfo* pause_info = GetOrAddLabelPauseInfo(event->label());
351 ASSERT(pause_info != NULL); 367 ASSERT(pause_info != NULL);
352 // |pause_info| will be running for |event->TimeDuration()|. 368 // |pause_info| will be running for |event->TimeDuration()|.
353 if (FLAG_trace_timeline_analysis) { 369 if (FLAG_trace_timeline_analysis) {
354 ISL_Print("Pushing %s %" Pd64 " us\n", 370 ISL_Print("Pushing %s %" Pd64 " us\n",
355 pause_info->name(), 371 pause_info->name(),
356 event->TimeDuration()); 372 event->TimeDuration());
357 } 373 }
358 pause_info->OnPush(event->TimeDuration()); 374 pause_info->OnPush(event->TimeDuration(), IsLabelOnStack(event->label()));
srdjan 2015/08/17 17:37:11 Is it better to do: if (!isLabelOnStack(..)) { p
Cutch 2015/08/17 17:51:12 At one point we needed the extra argument, right n
359 TimelineLabelPauseInfo* top_pause_info = GetTopLabel(); 375 if (StackDepth() > 0) {
360 if (top_pause_info != NULL) { 376 StackItem& top = GetStackTop();
361 // |top_pause_info| is under |event|'s shadow, adjust the exclusive micros. 377 // |top| is under |event|'s shadow, adjust the exclusive micros.
362 if (FLAG_trace_timeline_analysis) { 378 top.exclusive_micros -= event->TimeDuration();
363 ISL_Print("Adjusting %s by %" Pd64 " us\n",
364 top_pause_info->name(),
365 event->TimeDuration());
366 }
367 top_pause_info->OnChildPush(event->TimeDuration());
368 } 379 }
369 // Push onto the stack. 380 // Push onto the stack.
370 stack_.Add(event); 381 StackItem item;
382 item.event = event;
383 item.pause_info = pause_info;
384 item.exclusive_micros = event->TimeDuration();
385 stack_.Add(item);
371 } 386 }
372 387
373 388
374 TimelineLabelPauseInfo* TimelinePauses::GetTopLabel() { 389 bool TimelinePauses::IsLabelOnStack(const char* label) {
srdjan 2015/08/17 17:37:11 const
Cutch 2015/08/17 17:51:12 Done (in a CL I'm working on now).
375 if (stack_.length() == 0) { 390 ASSERT(label != NULL);
376 return NULL; 391 for (intptr_t i = 0; i < stack_.length(); i++) {
392 const StackItem& slot = stack_.At(i);
393 if (strcmp(slot.event->label(), label) == 0) {
394 return true;
395 }
377 } 396 }
378 TimelineEvent* event = stack_.Last(); 397 return false;
379 return GetLabel(event->label());
380 } 398 }
381 399
382 400
383 TimelineLabelPauseInfo* TimelinePauses::GetOrAddLabel(const char* name) { 401 intptr_t TimelinePauses::StackDepth() const {
402 return stack_.length();
403 }
404
405
406 TimelinePauses::StackItem& TimelinePauses::GetStackTop() {
srdjan 2015/08/17 17:37:11 const
Cutch 2015/08/17 17:51:12 Cannot be done because StackItem& is modified by t
407 ASSERT(stack_.length() > 0);
408 return stack_.Last();
409 }
410
411
412 TimelineLabelPauseInfo* TimelinePauses::GetOrAddLabelPauseInfo(
413 const char* name) {
384 ASSERT(name != NULL); 414 ASSERT(name != NULL);
385 TimelineLabelPauseInfo* label = GetLabel(name); 415 TimelineLabelPauseInfo* pause_info = GetLabelPauseInfo(name);
386 if (label != NULL) { 416 if (pause_info != NULL) {
387 return label; 417 return pause_info;
388 } 418 }
389 // New label. 419 // New label.
390 label = new TimelineLabelPauseInfo(name); 420 pause_info = new TimelineLabelPauseInfo(name);
391 labels_.Add(label); 421 labels_.Add(pause_info);
392 return label; 422 return pause_info;
393 } 423 }
394 424
395 } // namespace dart 425 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/timeline_analysis.h ('k') | runtime/vm/timeline_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698