| 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 #ifndef VM_TIMELINE_H_ | 5 #ifndef VM_TIMELINE_H_ |
| 6 #define VM_TIMELINE_H_ | 6 #define VM_TIMELINE_H_ |
| 7 | 7 |
| 8 #include "vm/bitfield.h" | 8 #include "vm/bitfield.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| 11 | 11 |
| 12 class JSONStream; | 12 class JSONStream; |
| 13 class Object; | 13 class Object; |
| 14 class RawArray; | 14 class RawArray; |
| 15 class Thread; | 15 class Thread; |
| 16 class TimelineEvent; | 16 class TimelineEvent; |
| 17 class TimelineEventBlock; |
| 17 class TimelineEventRecorder; | 18 class TimelineEventRecorder; |
| 18 class TimelineStream; | 19 class TimelineStream; |
| 19 | 20 |
| 20 // You should get a |TimelineEvent| from a |TimelineStream|. | 21 // You should get a |TimelineEvent| from a |TimelineStream|. |
| 21 class TimelineEvent { | 22 class TimelineEvent { |
| 22 public: | 23 public: |
| 23 // Keep in sync with StateBits below. | 24 // Keep in sync with StateBits below. |
| 24 enum EventType { | 25 enum EventType { |
| 25 kNone, | 26 kNone, |
| 26 kDuration, | 27 kDuration, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 } | 240 } |
| 240 event_->DurationEnd(); | 241 event_->DurationEnd(); |
| 241 event_->Complete(); | 242 event_->Complete(); |
| 242 } | 243 } |
| 243 | 244 |
| 244 private: | 245 private: |
| 245 TimelineEvent* event_; | 246 TimelineEvent* event_; |
| 246 }; | 247 }; |
| 247 | 248 |
| 248 | 249 |
| 250 // A block of |TimelineEvent|s. Not thread safe. |
| 251 class TimelineEventBlock { |
| 252 public: |
| 253 static const intptr_t kBlockSize = 64; |
| 254 |
| 255 TimelineEventBlock(); |
| 256 |
| 257 TimelineEventBlock* next() const { |
| 258 return next_; |
| 259 } |
| 260 void set_next(TimelineEventBlock* next) { |
| 261 next_ = next; |
| 262 } |
| 263 |
| 264 intptr_t length() const { |
| 265 return length_; |
| 266 } |
| 267 |
| 268 bool IsFull() const { |
| 269 return length_ == kBlockSize; |
| 270 } |
| 271 |
| 272 TimelineEvent* At(intptr_t index) { |
| 273 ASSERT(index >= 0); |
| 274 ASSERT(index < kBlockSize); |
| 275 return &events_[index]; |
| 276 } |
| 277 |
| 278 protected: |
| 279 TimelineEvent* StartEvent(); |
| 280 |
| 281 TimelineEvent events_[kBlockSize]; |
| 282 TimelineEventBlock* next_; |
| 283 intptr_t length_; |
| 284 |
| 285 friend class TimelineEventEndlessRecorder; |
| 286 |
| 287 private: |
| 288 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); |
| 289 }; |
| 290 |
| 291 |
| 249 // Recorder of |TimelineEvent|s. | 292 // Recorder of |TimelineEvent|s. |
| 250 class TimelineEventRecorder { | 293 class TimelineEventRecorder { |
| 251 public: | 294 public: |
| 252 TimelineEventRecorder(); | 295 TimelineEventRecorder(); |
| 253 virtual ~TimelineEventRecorder() {} | 296 virtual ~TimelineEventRecorder() {} |
| 254 | 297 |
| 255 // Interface method(s) which must be implemented. | 298 // Interface method(s) which must be implemented. |
| 256 virtual void PrintJSON(JSONStream* js) const = 0; | 299 virtual void PrintJSON(JSONStream* js) = 0; |
| 300 |
| 301 // Override if recorder uses blocks. |
| 302 virtual TimelineEventBlock* GetNewBlock() { |
| 303 return NULL; |
| 304 } |
| 257 | 305 |
| 258 void WriteTo(const char* directory); | 306 void WriteTo(const char* directory); |
| 259 | 307 |
| 260 protected: | 308 protected: |
| 261 // Interface method(s) which must be implemented. | 309 // Interface method(s) which must be implemented. |
| 262 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; | 310 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; |
| 263 virtual TimelineEvent* StartEvent(const Object& object) = 0; | 311 virtual TimelineEvent* StartEvent(const Object& object) = 0; |
| 264 virtual TimelineEvent* StartEvent() = 0; | 312 virtual TimelineEvent* StartEvent() = 0; |
| 265 virtual void CompleteEvent(TimelineEvent* event) = 0; | 313 virtual void CompleteEvent(TimelineEvent* event) = 0; |
| 266 | 314 |
| 267 // Utility method(s). | 315 // Utility method(s). |
| 268 void PrintJSONMeta(JSONArray* array) const; | 316 void PrintJSONMeta(JSONArray* array) const; |
| 269 | 317 |
| 270 friend class TimelineStream; | 318 friend class TimelineStream; |
| 271 friend class Isolate; | 319 friend class Isolate; |
| 272 | 320 |
| 273 private: | 321 private: |
| 274 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 322 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
| 275 }; | 323 }; |
| 276 | 324 |
| 277 | 325 |
| 278 // A recorder that stores events in a ring buffer of fixed capacity. | 326 // A recorder that stores events in a ring buffer of fixed capacity. |
| 327 // This recorder does track Dart objects. |
| 279 class TimelineEventRingRecorder : public TimelineEventRecorder { | 328 class TimelineEventRingRecorder : public TimelineEventRecorder { |
| 280 public: | 329 public: |
| 281 static const intptr_t kDefaultCapacity = 8192; | 330 static const intptr_t kDefaultCapacity = 8192; |
| 282 | 331 |
| 283 static intptr_t SizeForCapacity(intptr_t capacity); | 332 static intptr_t SizeForCapacity(intptr_t capacity); |
| 284 | 333 |
| 285 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); | 334 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); |
| 286 ~TimelineEventRingRecorder(); | 335 ~TimelineEventRingRecorder(); |
| 287 | 336 |
| 288 void PrintJSON(JSONStream* js) const; | 337 void PrintJSON(JSONStream* js); |
| 289 | 338 |
| 290 protected: | 339 protected: |
| 291 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 340 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 292 TimelineEvent* StartEvent(const Object& object); | 341 TimelineEvent* StartEvent(const Object& object); |
| 293 TimelineEvent* StartEvent(); | 342 TimelineEvent* StartEvent(); |
| 294 void CompleteEvent(TimelineEvent* event); | 343 void CompleteEvent(TimelineEvent* event); |
| 295 | 344 |
| 296 void PrintJSONEvents(JSONArray* array) const; | 345 void PrintJSONEvents(JSONArray* array) const; |
| 297 | 346 |
| 298 intptr_t GetNextIndex(); | 347 intptr_t GetNextIndex(); |
| 299 | 348 |
| 300 // events_[i] and event_objects_[i] are indexed together. | 349 // events_[i] and event_objects_[i] are indexed together. |
| 301 TimelineEvent* events_; | 350 TimelineEvent* events_; |
| 302 RawArray* event_objects_; | 351 RawArray* event_objects_; |
| 303 uintptr_t cursor_; | 352 uintptr_t cursor_; |
| 304 intptr_t capacity_; | 353 intptr_t capacity_; |
| 305 }; | 354 }; |
| 306 | 355 |
| 307 | 356 |
| 308 // An abstract recorder that calls |StreamEvent| whenever an event is complete. | 357 // An abstract recorder that calls |StreamEvent| whenever an event is complete. |
| 309 // This recorder does not track Dart objects. | 358 // This recorder does not track Dart objects. |
| 310 class TimelineEventStreamingRecorder : public TimelineEventRecorder { | 359 class TimelineEventStreamingRecorder : public TimelineEventRecorder { |
| 311 public: | 360 public: |
| 312 TimelineEventStreamingRecorder(); | 361 TimelineEventStreamingRecorder(); |
| 313 ~TimelineEventStreamingRecorder(); | 362 ~TimelineEventStreamingRecorder(); |
| 314 | 363 |
| 315 void PrintJSON(JSONStream* js) const; | 364 void PrintJSON(JSONStream* js); |
| 316 | 365 |
| 317 // Called when |event| is ready to be streamed. It is unsafe to keep a | 366 // Called when |event| is ready to be streamed. It is unsafe to keep a |
| 318 // reference to |event| as it may be freed as soon as this function returns. | 367 // reference to |event| as it may be freed as soon as this function returns. |
| 319 virtual void StreamEvent(TimelineEvent* event) = 0; | 368 virtual void StreamEvent(TimelineEvent* event) = 0; |
| 320 | 369 |
| 321 protected: | 370 protected: |
| 322 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 371 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 323 TimelineEvent* StartEvent(const Object& object); | 372 TimelineEvent* StartEvent(const Object& object); |
| 324 TimelineEvent* StartEvent(); | 373 TimelineEvent* StartEvent(); |
| 325 void CompleteEvent(TimelineEvent* event); | 374 void CompleteEvent(TimelineEvent* event); |
| 326 }; | 375 }; |
| 327 | 376 |
| 377 |
| 378 // A recorder that stores events in chains of blocks of events. |
| 379 // This recorder does not track Dart objects. |
| 380 // NOTE: This recorder will continue to allocate blocks until it exhausts |
| 381 // memory. |
| 382 class TimelineEventEndlessRecorder : public TimelineEventRecorder { |
| 383 public: |
| 384 TimelineEventEndlessRecorder(); |
| 385 |
| 386 // Acquire a new block of events. |
| 387 // Takes a lock. |
| 388 // Recorder owns the block and it should be filled by only one thread. |
| 389 TimelineEventBlock* GetNewBlock(); |
| 390 |
| 391 // It is expected that this function is only called when an isolate is |
| 392 // shutting itself down. |
| 393 // NOTE: Calling this while threads are filling in their blocks is not safe |
| 394 // and there are no checks in place to ensure that doesn't happen. |
| 395 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1. |
| 396 void PrintJSON(JSONStream* js); |
| 397 |
| 398 protected: |
| 399 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 400 TimelineEvent* StartEvent(const Object& object); |
| 401 TimelineEvent* StartEvent(); |
| 402 void CompleteEvent(TimelineEvent* event); |
| 403 |
| 404 TimelineEventBlock* GetNewBlockLocked(); |
| 405 void PrintJSONEvents(JSONArray* array) const; |
| 406 |
| 407 Mutex lock_; |
| 408 TimelineEventBlock* head_; |
| 409 }; |
| 410 |
| 328 } // namespace dart | 411 } // namespace dart |
| 329 | 412 |
| 330 #endif // VM_TIMELINE_H_ | 413 #endif // VM_TIMELINE_H_ |
| OLD | NEW |