Chromium Code Reviews| 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); | |
|
Ivan Posva
2013/11/07 22:36:28
Could also convert from micros to doubles here.
Cutch
2013/11/13 17:33:14
Done.
| |
| 112 trace_entry.AddProperty("message", entry.message); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 } // namespace dart | |
| OLD | NEW |