OLD | NEW |
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 <cstdlib> | 5 #include <cstdlib> |
6 | 6 |
7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
8 #include "vm/json_stream.h" | 8 #include "vm/json_stream.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/thread.h" | 10 #include "vm/thread.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 void TimelineEvent::Reset() { | 34 void TimelineEvent::Reset() { |
35 set_event_type(kNone); | 35 set_event_type(kNone); |
36 thread_ = NULL; | 36 thread_ = NULL; |
37 stream_ = NULL; | 37 stream_ = NULL; |
38 label_ = NULL; | 38 label_ = NULL; |
39 FreeArguments(); | 39 FreeArguments(); |
40 } | 40 } |
41 | 41 |
42 | 42 |
43 int64_t TimelineEvent::AsyncBegin(TimelineStream* stream, const char* label) { | 43 int64_t TimelineEvent::AsyncBegin(const char* label) { |
44 Init(kAsyncBegin, stream, label); | 44 Init(kAsyncBegin, label); |
45 timestamp0_ = OS::GetCurrentTimeMicros(); | 45 timestamp0_ = OS::GetCurrentTimeMicros(); |
46 int64_t async_id = stream->GetNextSeq(); | 46 ASSERT(stream_ != NULL); |
| 47 int64_t async_id = stream_->GetNextSeq(); |
47 // Overload timestamp1_ with the async_id. | 48 // Overload timestamp1_ with the async_id. |
48 timestamp1_ = async_id; | 49 timestamp1_ = async_id; |
49 return async_id; | 50 return async_id; |
50 } | 51 } |
51 | 52 |
52 | 53 |
53 void TimelineEvent::AsyncInstant(TimelineStream* stream, | 54 void TimelineEvent::AsyncInstant(const char* label, |
54 const char* label, | |
55 int64_t async_id) { | 55 int64_t async_id) { |
56 Init(kAsyncInstant, stream, label); | 56 Init(kAsyncInstant, label); |
57 timestamp0_ = OS::GetCurrentTimeMicros(); | 57 timestamp0_ = OS::GetCurrentTimeMicros(); |
58 // Overload timestamp1_ with the async_id. | 58 // Overload timestamp1_ with the async_id. |
59 timestamp1_ = async_id; | 59 timestamp1_ = async_id; |
60 } | 60 } |
61 | 61 |
62 | 62 |
63 void TimelineEvent::AsyncEnd(TimelineStream* stream, | 63 void TimelineEvent::AsyncEnd(const char* label, |
64 const char* label, | |
65 int64_t async_id) { | 64 int64_t async_id) { |
66 Init(kAsyncEnd, stream, label); | 65 Init(kAsyncEnd, label); |
67 timestamp0_ = OS::GetCurrentTimeMicros(); | 66 timestamp0_ = OS::GetCurrentTimeMicros(); |
68 // Overload timestamp1_ with the async_id. | 67 // Overload timestamp1_ with the async_id. |
69 timestamp1_ = async_id; | 68 timestamp1_ = async_id; |
70 } | 69 } |
71 | 70 |
72 | 71 |
73 void TimelineEvent::DurationBegin(TimelineStream* stream, const char* label) { | 72 void TimelineEvent::DurationBegin(const char* label) { |
74 Init(kDuration, stream, label); | 73 Init(kDuration, label); |
75 timestamp0_ = OS::GetCurrentTimeMicros(); | 74 timestamp0_ = OS::GetCurrentTimeMicros(); |
76 } | 75 } |
77 | 76 |
78 | 77 |
79 void TimelineEvent::DurationEnd() { | 78 void TimelineEvent::DurationEnd() { |
80 timestamp1_ = OS::GetCurrentTimeMicros(); | 79 timestamp1_ = OS::GetCurrentTimeMicros(); |
81 } | 80 } |
82 | 81 |
83 | 82 |
84 void TimelineEvent::Instant(TimelineStream* stream, | 83 void TimelineEvent::Instant(const char* label) { |
85 const char* label) { | 84 Init(kInstant, label); |
86 Init(kInstant, stream, label); | |
87 timestamp0_ = OS::GetCurrentTimeMicros(); | 85 timestamp0_ = OS::GetCurrentTimeMicros(); |
88 } | 86 } |
89 | 87 |
90 | 88 |
91 void TimelineEvent::Duration(TimelineStream* stream, | 89 void TimelineEvent::Duration(const char* label, |
92 const char* label, | |
93 int64_t start_micros, | 90 int64_t start_micros, |
94 int64_t end_micros) { | 91 int64_t end_micros) { |
95 Init(kDuration, stream, label); | 92 Init(kDuration, label); |
96 timestamp0_ = start_micros; | 93 timestamp0_ = start_micros; |
97 timestamp1_ = end_micros; | 94 timestamp1_ = end_micros; |
98 } | 95 } |
99 | 96 |
100 | 97 |
101 void TimelineEvent::SetNumArguments(intptr_t length) { | 98 void TimelineEvent::SetNumArguments(intptr_t length) { |
102 // Cannot call this twice. | 99 // Cannot call this twice. |
103 ASSERT(arguments_ == NULL); | 100 ASSERT(arguments_ == NULL); |
104 ASSERT(arguments_length_ == 0); | 101 ASSERT(arguments_length_ == 0); |
105 arguments_length_ = length; | 102 arguments_length_ = length; |
(...skipping 29 matching lines...) Expand all Loading... |
135 } | 132 } |
136 | 133 |
137 | 134 |
138 void TimelineEvent::CopyArgument(intptr_t i, | 135 void TimelineEvent::CopyArgument(intptr_t i, |
139 const char* name, | 136 const char* name, |
140 const char* argument) { | 137 const char* argument) { |
141 SetArgument(i, name, strdup(argument)); | 138 SetArgument(i, name, strdup(argument)); |
142 } | 139 } |
143 | 140 |
144 | 141 |
| 142 void TimelineEvent::Complete() { |
| 143 stream_->CompleteEvent(this); |
| 144 } |
| 145 |
| 146 |
145 void TimelineEvent::FreeArguments() { | 147 void TimelineEvent::FreeArguments() { |
146 if (arguments_ == NULL) { | 148 if (arguments_ == NULL) { |
147 return; | 149 return; |
148 } | 150 } |
149 for (intptr_t i = 0; i < arguments_length_; i++) { | 151 for (intptr_t i = 0; i < arguments_length_; i++) { |
150 free(arguments_[i].value); | 152 free(arguments_[i].value); |
151 } | 153 } |
152 free(arguments_); | 154 free(arguments_); |
153 arguments_ = NULL; | 155 arguments_ = NULL; |
154 arguments_length_ = 0; | 156 arguments_length_ = 0; |
155 } | 157 } |
156 | 158 |
| 159 |
| 160 void TimelineEvent::StreamInit(TimelineStream* stream) { |
| 161 ASSERT(stream != NULL); |
| 162 stream_ = stream; |
| 163 } |
| 164 |
| 165 |
157 void TimelineEvent::Init(EventType event_type, | 166 void TimelineEvent::Init(EventType event_type, |
158 TimelineStream* stream, | |
159 const char* label) { | 167 const char* label) { |
160 ASSERT(stream != NULL); | |
161 ASSERT(label != NULL); | 168 ASSERT(label != NULL); |
162 set_event_type(event_type); | 169 set_event_type(event_type); |
163 timestamp0_ = 0; | 170 timestamp0_ = 0; |
164 timestamp1_ = 0; | 171 timestamp1_ = 0; |
165 thread_ = Thread::Current(); | 172 thread_ = Thread::Current(); |
166 stream_ = stream; | |
167 label_ = label; | 173 label_ = label; |
168 FreeArguments(); | 174 FreeArguments(); |
169 } | 175 } |
170 | 176 |
171 | 177 |
172 static int64_t GetPid(Isolate* isolate) { | 178 static int64_t GetPid(Isolate* isolate) { |
173 // Some mapping from Isolate* to an integer process id. | 179 // Some mapping from Isolate* to an integer process id. |
174 // TODO(Cutch): Investigate if process ids can be strings. | 180 // TODO(Cutch): Investigate if process ids can be strings. |
175 return static_cast<int64_t>(reinterpret_cast<uintptr_t>(isolate)); | 181 return static_cast<int64_t>(reinterpret_cast<uintptr_t>(isolate)); |
176 } | 182 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 int64_t TimelineEvent::TimeDuration() const { | 251 int64_t TimelineEvent::TimeDuration() const { |
246 if (timestamp1_ == 0) { | 252 if (timestamp1_ == 0) { |
247 // This duration is still open, use current time as end. | 253 // This duration is still open, use current time as end. |
248 return OS::GetCurrentTimeMicros() - timestamp0_; | 254 return OS::GetCurrentTimeMicros() - timestamp0_; |
249 } | 255 } |
250 return timestamp1_ - timestamp0_; | 256 return timestamp1_ - timestamp0_; |
251 } | 257 } |
252 | 258 |
253 | 259 |
254 TimelineStream::TimelineStream() | 260 TimelineStream::TimelineStream() |
255 : buffer_(NULL), | 261 : recorder_(NULL), |
256 name_(NULL), | 262 name_(NULL), |
257 enabled_(false), | 263 enabled_(false), |
258 seq_(0) { | 264 seq_(0) { |
259 } | 265 } |
260 | 266 |
261 | 267 |
262 void TimelineStream::Init(const char* name, bool enabled) { | 268 void TimelineStream::Init(const char* name, bool enabled) { |
263 name_ = name; | 269 name_ = name; |
264 enabled_ = enabled; | 270 enabled_ = enabled; |
265 } | 271 } |
266 | 272 |
267 | 273 |
268 TimelineEvent* TimelineStream::RecordEvent(const Object& obj) { | 274 TimelineEvent* TimelineStream::StartEvent(const Object& obj) { |
269 if (!enabled_ || (buffer_ == NULL)) { | 275 if (!enabled_ || (recorder_ == NULL)) { |
270 return NULL; | 276 return NULL; |
271 } | 277 } |
272 ASSERT(name_ != NULL); | 278 ASSERT(name_ != NULL); |
273 ASSERT(buffer_ != NULL); | 279 ASSERT(recorder_ != NULL); |
274 return buffer_->RecordEvent(obj); | 280 TimelineEvent* event = recorder_->StartEvent(obj); |
| 281 if (event != NULL) { |
| 282 event->StreamInit(this); |
| 283 } |
| 284 return event; |
275 } | 285 } |
276 | 286 |
277 | 287 |
278 TimelineEvent* TimelineStream::RecordEvent() { | 288 TimelineEvent* TimelineStream::StartEvent() { |
279 if (!enabled_ || (buffer_ == NULL)) { | 289 if (!enabled_ || (recorder_ == NULL)) { |
280 return NULL; | 290 return NULL; |
281 } | 291 } |
282 ASSERT(name_ != NULL); | 292 ASSERT(name_ != NULL); |
283 return buffer_->RecordEvent(); | 293 TimelineEvent* event = recorder_->StartEvent(); |
| 294 if (event != NULL) { |
| 295 event->StreamInit(this); |
| 296 } |
| 297 return event; |
284 } | 298 } |
285 | 299 |
286 | 300 |
| 301 void TimelineStream::CompleteEvent(TimelineEvent* event) { |
| 302 if (!enabled_ || (recorder_ == NULL)) { |
| 303 return; |
| 304 } |
| 305 recorder_->CompleteEvent(event); |
| 306 } |
| 307 |
| 308 |
287 int64_t TimelineStream::GetNextSeq() { | 309 int64_t TimelineStream::GetNextSeq() { |
288 seq_++; | 310 seq_++; |
289 if (seq_ < 0) { | 311 if (seq_ < 0) { |
290 seq_ = 0; | 312 seq_ = 0; |
291 } | 313 } |
292 return seq_; | 314 return seq_; |
293 } | 315 } |
294 | 316 |
295 | 317 |
296 void TimelineDurationScope::FormatArgument(intptr_t i, | 318 void TimelineDurationScope::FormatArgument(intptr_t i, |
(...skipping 10 matching lines...) Expand all Loading... |
307 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 329 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
308 va_list args2; | 330 va_list args2; |
309 va_start(args2, fmt); | 331 va_start(args2, fmt); |
310 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 332 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
311 va_end(args2); | 333 va_end(args2); |
312 | 334 |
313 event_->SetArgument(i, name, buffer); | 335 event_->SetArgument(i, name, buffer); |
314 } | 336 } |
315 | 337 |
316 | 338 |
317 intptr_t TimelineEventBuffer::SizeForCapacity(intptr_t capacity) { | 339 TimelineEventRecorder::TimelineEventRecorder() { |
| 340 } |
| 341 |
| 342 |
| 343 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
| 344 Isolate* isolate = Isolate::Current(); |
| 345 JSONObject obj(events); |
| 346 int64_t pid = GetPid(isolate); |
| 347 obj.AddProperty("ph", "M"); |
| 348 obj.AddProperty64("pid", pid); |
| 349 obj.AddProperty("name", "process_name"); |
| 350 { |
| 351 JSONObject args(&obj, "args"); |
| 352 args.AddProperty("name", isolate->debugger_name()); |
| 353 } |
| 354 } |
| 355 |
| 356 |
| 357 void TimelineEventRecorder::WriteTo(const char* directory) { |
| 358 Isolate* isolate = Isolate::Current(); |
| 359 |
| 360 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); |
| 361 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); |
| 362 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); |
| 363 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
| 364 return; |
| 365 } |
| 366 |
| 367 JSONStream js; |
| 368 PrintJSON(&js); |
| 369 |
| 370 const char* format = "%s/dart-timeline-%" Pd "-%" Pd ".json"; |
| 371 intptr_t pid = OS::ProcessId(); |
| 372 intptr_t len = OS::SNPrint(NULL, 0, format, |
| 373 directory, pid, isolate->main_port()); |
| 374 char* filename = isolate->current_zone()->Alloc<char>(len + 1); |
| 375 OS::SNPrint(filename, len + 1, format, |
| 376 directory, pid, isolate->main_port()); |
| 377 void* file = (*file_open)(filename, true); |
| 378 if (file == NULL) { |
| 379 OS::Print("Failed to write timeline file: %s\n", filename); |
| 380 return; |
| 381 } |
| 382 (*file_write)(js.buffer()->buf(), js.buffer()->length(), file); |
| 383 (*file_close)(file); |
| 384 } |
| 385 |
| 386 |
| 387 intptr_t TimelineEventRingRecorder::SizeForCapacity(intptr_t capacity) { |
318 return sizeof(TimelineEvent) * capacity; | 388 return sizeof(TimelineEvent) * capacity; |
319 } | 389 } |
320 | 390 |
321 | 391 |
322 TimelineEventBuffer::TimelineEventBuffer(intptr_t capacity) | 392 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) |
323 : events_(NULL), | 393 : events_(NULL), |
324 event_objects_(Array::null()), | 394 event_objects_(Array::null()), |
325 cursor_(0), | 395 cursor_(0), |
326 capacity_(capacity) { | 396 capacity_(capacity) { |
327 if (FLAG_trace_timeline) { | 397 if (FLAG_trace_timeline) { |
328 // 32-bit: 262,144 bytes per isolate. | 398 // 32-bit: 262,144 bytes per isolate. |
329 // 64-bit: 393,216 bytes per isolate. | 399 // 64-bit: 393,216 bytes per isolate. |
330 // NOTE: Internal isolates (vm and service) do not have a timeline | 400 // NOTE: Internal isolates (vm and service) do not have a timeline |
331 // event buffer. | 401 // event buffer. |
332 OS::Print("TimelineEventBuffer is %" Pd " bytes (%" Pd " events)\n", | 402 OS::Print("TimelineEventRingRecorder is %" Pd " bytes (%" Pd " events)\n", |
333 SizeForCapacity(capacity), | 403 SizeForCapacity(capacity), |
334 capacity); | 404 capacity); |
335 } | 405 } |
336 events_ = | 406 events_ = |
337 reinterpret_cast<TimelineEvent*>(calloc(capacity, sizeof(TimelineEvent))); | 407 reinterpret_cast<TimelineEvent*>(calloc(capacity, sizeof(TimelineEvent))); |
338 const Array& array = Array::Handle(Array::New(capacity, Heap::kOld)); | 408 const Array& array = Array::Handle(Array::New(capacity, Heap::kOld)); |
339 event_objects_ = array.raw(); | 409 event_objects_ = array.raw(); |
340 } | 410 } |
341 | 411 |
342 | 412 |
343 TimelineEventBuffer::~TimelineEventBuffer() { | 413 TimelineEventRingRecorder::~TimelineEventRingRecorder() { |
344 for (intptr_t i = 0; i < capacity_; i++) { | 414 for (intptr_t i = 0; i < capacity_; i++) { |
345 // Clear any extra data. | 415 // Clear any extra data. |
346 events_[i].Reset(); | 416 events_[i].Reset(); |
347 } | 417 } |
348 free(events_); | 418 free(events_); |
349 event_objects_ = Array::null(); | 419 event_objects_ = Array::null(); |
350 } | 420 } |
351 | 421 |
352 | 422 |
353 void TimelineEventBuffer::PrintJSONMeta(JSONArray* events) const { | 423 void TimelineEventRingRecorder::PrintJSONEvents(JSONArray* events) const { |
354 Isolate* isolate = Isolate::Current(); | |
355 JSONObject obj(events); | |
356 int64_t pid = GetPid(isolate); | |
357 obj.AddProperty("ph", "M"); | |
358 obj.AddProperty64("pid", pid); | |
359 obj.AddProperty("name", "process_name"); | |
360 { | |
361 JSONObject args(&obj, "args"); | |
362 args.AddProperty("name", isolate->debugger_name()); | |
363 } | |
364 } | |
365 | |
366 | |
367 void TimelineEventBuffer::PrintJSONEvents(JSONArray* events) const { | |
368 for (intptr_t i = 0; i < capacity_; i++) { | 424 for (intptr_t i = 0; i < capacity_; i++) { |
369 if (events_[i].IsValid()) { | 425 if (events_[i].IsValid()) { |
370 events->AddValue(&events_[i]); | 426 events->AddValue(&events_[i]); |
371 } | 427 } |
372 } | 428 } |
373 } | 429 } |
374 | 430 |
375 | 431 |
376 void TimelineEventBuffer::PrintJSON(JSONStream* js) const { | 432 void TimelineEventRingRecorder::PrintJSON(JSONStream* js) const { |
377 JSONObject topLevel(js); | 433 JSONObject topLevel(js); |
378 topLevel.AddProperty("type", "_Timeline"); | 434 topLevel.AddProperty("type", "_Timeline"); |
379 { | 435 { |
380 JSONArray events(&topLevel, "traceEvents"); | 436 JSONArray events(&topLevel, "traceEvents"); |
381 PrintJSONMeta(&events); | 437 PrintJSONMeta(&events); |
382 PrintJSONEvents(&events); | 438 PrintJSONEvents(&events); |
383 } | 439 } |
384 } | 440 } |
385 | 441 |
386 | 442 |
387 void TimelineEventBuffer::WriteTo(const char* directory) { | 443 intptr_t TimelineEventRingRecorder::GetNextIndex() { |
388 Isolate* isolate = Isolate::Current(); | |
389 | |
390 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | |
391 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); | |
392 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | |
393 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | |
394 return; | |
395 } | |
396 | |
397 JSONStream js; | |
398 PrintJSON(&js); | |
399 | |
400 const char* format = "%s/dart-timeline-%" Pd "-%" Pd ".json"; | |
401 intptr_t pid = OS::ProcessId(); | |
402 intptr_t len = OS::SNPrint(NULL, 0, format, | |
403 directory, pid, isolate->main_port()); | |
404 char* filename = isolate->current_zone()->Alloc<char>(len + 1); | |
405 OS::SNPrint(filename, len + 1, format, | |
406 directory, pid, isolate->main_port()); | |
407 void* file = (*file_open)(filename, true); | |
408 if (file == NULL) { | |
409 OS::Print("Failed to write timeline file: %s\n", filename); | |
410 return; | |
411 } | |
412 (*file_write)(js.buffer()->buf(), js.buffer()->length(), file); | |
413 (*file_close)(file); | |
414 } | |
415 | |
416 | |
417 intptr_t TimelineEventBuffer::GetNextIndex() { | |
418 uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_); | 444 uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_); |
419 return cursor % capacity_; | 445 return cursor % capacity_; |
420 } | 446 } |
421 | 447 |
422 | 448 |
423 void TimelineEventBuffer::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 449 void TimelineEventRingRecorder::VisitObjectPointers( |
| 450 ObjectPointerVisitor* visitor) { |
424 visitor->VisitPointer(reinterpret_cast<RawObject**>(&event_objects_)); | 451 visitor->VisitPointer(reinterpret_cast<RawObject**>(&event_objects_)); |
425 } | 452 } |
426 | 453 |
427 | 454 |
428 TimelineEvent* TimelineEventBuffer::RecordEvent(const Object& obj) { | 455 TimelineEvent* TimelineEventRingRecorder::StartEvent(const Object& obj) { |
429 ASSERT(events_ != NULL); | 456 ASSERT(events_ != NULL); |
430 uintptr_t index = GetNextIndex(); | 457 uintptr_t index = GetNextIndex(); |
431 const Array& event_objects = Array::Handle(event_objects_); | 458 const Array& event_objects = Array::Handle(event_objects_); |
432 event_objects.SetAt(index, obj); | 459 event_objects.SetAt(index, obj); |
433 return &events_[index]; | 460 return &events_[index]; |
434 } | 461 } |
435 | 462 |
436 | 463 |
437 TimelineEvent* TimelineEventBuffer::RecordEvent() { | 464 TimelineEvent* TimelineEventRingRecorder::StartEvent() { |
438 ASSERT(events_ != NULL); | 465 ASSERT(events_ != NULL); |
439 uintptr_t index = GetNextIndex(); | 466 uintptr_t index = GetNextIndex(); |
440 return &events_[index]; | 467 return &events_[index]; |
441 } | 468 } |
442 | 469 |
| 470 void TimelineEventRingRecorder::CompleteEvent(TimelineEvent* event) { |
| 471 ASSERT(events_ != NULL); |
| 472 // no-op. |
| 473 } |
| 474 |
| 475 |
| 476 TimelineEventStreamingRecorder::TimelineEventStreamingRecorder() { |
| 477 } |
| 478 |
| 479 |
| 480 TimelineEventStreamingRecorder::~TimelineEventStreamingRecorder() { |
| 481 } |
| 482 |
| 483 |
| 484 void TimelineEventStreamingRecorder::PrintJSON(JSONStream* js) const { |
| 485 JSONObject topLevel(js); |
| 486 topLevel.AddProperty("type", "_Timeline"); |
| 487 { |
| 488 JSONArray events(&topLevel, "traceEvents"); |
| 489 PrintJSONMeta(&events); |
| 490 } |
| 491 } |
| 492 |
| 493 void TimelineEventStreamingRecorder::VisitObjectPointers( |
| 494 ObjectPointerVisitor* visitor) { |
| 495 // no-op. |
| 496 } |
| 497 |
| 498 |
| 499 TimelineEvent* TimelineEventStreamingRecorder::StartEvent( |
| 500 const Object& object) { |
| 501 // The streaming recorder does not track Dart objects. |
| 502 return StartEvent(); |
| 503 } |
| 504 |
| 505 |
| 506 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { |
| 507 TimelineEvent* event = new TimelineEvent(); |
| 508 return event; |
| 509 } |
| 510 |
| 511 |
| 512 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { |
| 513 StreamEvent(event); |
| 514 delete event; |
| 515 } |
| 516 |
443 } // namespace dart | 517 } // namespace dart |
OLD | NEW |