OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #include "vm/json_stream.h" |
| 6 #include "vm/os.h" |
| 7 #include "vm/trace_buffer.h" |
| 8 |
| 9 namespace dart { |
| 10 |
| 11 TraceBuffer::TraceBuffer(intptr_t capacity) { |
| 12 ring_capacity_ = capacity; |
| 13 ring_start_ = 0; |
| 14 ring_size_ = 0; |
| 15 Init(); |
| 16 } |
| 17 |
| 18 |
| 19 TraceBuffer::~TraceBuffer() { |
| 20 ASSERT(ring_ != NULL); |
| 21 Clear(); |
| 22 free(ring_); |
| 23 } |
| 24 |
| 25 |
| 26 void TraceBuffer::Init() { |
| 27 ring_ = reinterpret_cast<TraceBufferEntry*>( |
| 28 calloc(ring_capacity_, sizeof(TraceBufferEntry))); // NOLINT |
| 29 } |
| 30 |
| 31 |
| 32 void TraceBuffer::Clear() { |
| 33 const intptr_t last = ring_start_ + ring_size_; |
| 34 for (intptr_t i = ring_start_; i < last; i++) { |
| 35 intptr_t index = RingIndex(i); |
| 36 TraceBufferEntry& entry = ring_[index]; |
| 37 entry.seconds = 0.0; |
| 38 free(entry.message); |
| 39 entry.message = NULL; |
| 40 } |
| 41 ring_start_ = 0; |
| 42 ring_size_ = 0; |
| 43 } |
| 44 |
| 45 |
| 46 void TraceBuffer::Fill(TraceBufferEntry* entry, double seconds, char* msg) { |
| 47 if (entry->message != NULL) { |
| 48 // Recycle TraceBufferEntry. |
| 49 free(entry->message); |
| 50 } |
| 51 entry->message = msg; |
| 52 entry->seconds = seconds; |
| 53 } |
| 54 |
| 55 |
| 56 void TraceBuffer::AppendTrace(int64_t time, char* message) { |
| 57 double seconds = static_cast<double>(time) / |
| 58 static_cast<double>(kMicrosecondsPerSecond); |
| 59 intptr_t index; |
| 60 if (ring_size_ == ring_capacity_) { |
| 61 // Bite off tail. |
| 62 index = ring_start_; |
| 63 ring_start_ = RingIndex(ring_start_ + 1); |
| 64 } else { |
| 65 ASSERT(ring_size_ < ring_capacity_); |
| 66 index = ring_size_; |
| 67 ring_size_++; |
| 68 } |
| 69 TraceBufferEntry* trace_entry = &ring_[index]; |
| 70 Fill(trace_entry, seconds, message); |
| 71 } |
| 72 |
| 73 |
| 74 void TraceBuffer::Trace(int64_t time, const char* message) { |
| 75 ASSERT(message != NULL); |
| 76 char* message_copy = strdup(message); |
| 77 AppendTrace(time, message_copy); |
| 78 } |
| 79 |
| 80 |
| 81 void TraceBuffer::Trace(const char* message) { |
| 82 Trace(OS::GetCurrentTimeMicros(), message); |
| 83 } |
| 84 |
| 85 |
| 86 void TraceBuffer::TraceF(const char* format, ...) { |
| 87 int64_t time = OS::GetCurrentTimeMicros(); |
| 88 va_list args; |
| 89 va_start(args, format); |
| 90 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 91 va_end(args); |
| 92 char* p = reinterpret_cast<char*>(malloc(len+1)); |
| 93 va_start(args, format); |
| 94 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); |
| 95 va_end(args); |
| 96 ASSERT(len == len2); |
| 97 AppendTrace(time, p); |
| 98 } |
| 99 |
| 100 |
| 101 void TraceBuffer::PrintToJSONStream(JSONStream* stream) const { |
| 102 JSONObject json_trace_buffer(stream); |
| 103 json_trace_buffer.AddProperty("type", "TraceBuffer"); |
| 104 JSONArray json_trace_buffer_array(&json_trace_buffer, "members"); |
| 105 const intptr_t last = ring_start_ + ring_size_; |
| 106 for (intptr_t i = ring_start_; i < last; i++) { |
| 107 intptr_t index = RingIndex(i); |
| 108 const TraceBufferEntry& entry = ring_[index]; |
| 109 JSONObject trace_entry(&json_trace_buffer_array); |
| 110 trace_entry.AddProperty("type", "TraceBufferEntry"); |
| 111 trace_entry.AddProperty("time", entry.seconds); |
| 112 trace_entry.AddProperty("message", entry.message); |
| 113 } |
| 114 } |
| 115 |
| 116 } // namespace dart |
OLD | NEW |