Chromium Code Reviews| Index: runtime/vm/trace_buffer.cc |
| diff --git a/runtime/vm/trace_buffer.cc b/runtime/vm/trace_buffer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b3a98991d088be9c202925d25db2bbdf6a9481f3 |
| --- /dev/null |
| +++ b/runtime/vm/trace_buffer.cc |
| @@ -0,0 +1,116 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#include "vm/json_stream.h" |
| +#include "vm/os.h" |
| +#include "vm/trace_buffer.h" |
| + |
| +namespace dart { |
| + |
| +TraceBuffer::TraceBuffer(intptr_t capacity) { |
| + ring_capacity_ = capacity; |
| + ring_start_ = 0; |
| + ring_size_ = 0; |
| + Init(); |
| +} |
| + |
| + |
| +TraceBuffer::~TraceBuffer() { |
| + ASSERT(ring_ != NULL); |
| + Clear(); |
| + free(ring_); |
| +} |
| + |
| + |
| +void TraceBuffer::Init() { |
| + ring_ = reinterpret_cast<TraceBufferEntry*>( |
| + calloc(ring_capacity_, sizeof(TraceBufferEntry))); // NOLINT |
| +} |
| + |
| + |
| +void TraceBuffer::Clear() { |
| + const intptr_t last = ring_start_ + ring_size_; |
| + for (intptr_t i = ring_start_; i < last; i++) { |
| + intptr_t index = RingIndex(i); |
| + TraceBufferEntry& entry = ring_[index]; |
| + entry.seconds = 0.0; |
| + free(entry.message); |
| + entry.message = NULL; |
| + } |
| + ring_start_ = 0; |
| + ring_size_ = 0; |
| +} |
| + |
| + |
| +void TraceBuffer::Fill(TraceBufferEntry* entry, double seconds, char* msg) { |
| + if (entry->message != NULL) { |
| + // Recycle TraceBufferEntry. |
| + free(entry->message); |
| + } |
| + entry->message = msg; |
| + entry->seconds = seconds; |
| +} |
| + |
| + |
| +void TraceBuffer::AppendTrace(int64_t time, char* message) { |
| + double seconds = static_cast<double>(time) / |
| + static_cast<double>(kMicrosecondsPerSecond); |
| + intptr_t index; |
| + if (ring_size_ == ring_capacity_) { |
| + // Bite off tail. |
| + index = ring_start_; |
| + ring_start_ = RingIndex(ring_start_ + 1); |
| + } else { |
| + ASSERT(ring_size_ < ring_capacity_); |
| + index = ring_size_; |
| + ring_size_++; |
| + } |
| + TraceBufferEntry* trace_entry = &ring_[index]; |
| + Fill(trace_entry, seconds, message); |
| +} |
| + |
| + |
| +void TraceBuffer::Trace(int64_t time, const char* message) { |
| + ASSERT(message != NULL); |
| + char* message_copy = strdup(message); |
| + AppendTrace(time, message_copy); |
| +} |
| + |
| + |
| +void TraceBuffer::Trace(const char* message) { |
| + Trace(OS::GetCurrentTimeMicros(), message); |
| +} |
| + |
| + |
| +void TraceBuffer::TraceF(const char* format, ...) { |
| + int64_t time = OS::GetCurrentTimeMicros(); |
| + va_list args; |
| + va_start(args, format); |
| + intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| + va_end(args); |
| + char* p = reinterpret_cast<char*>(malloc(len+1)); |
| + va_start(args, format); |
| + intptr_t len2 = OS::VSNPrint(p, len+1, format, args); |
| + va_end(args); |
| + ASSERT(len == len2); |
| + AppendTrace(time, p); |
| +} |
| + |
| + |
| +void TraceBuffer::PrintToJSONStream(JSONStream* stream) const { |
| + JSONObject json_trace_buffer(stream); |
| + json_trace_buffer.AddProperty("type", "TraceBuffer"); |
| + JSONArray json_trace_buffer_array(&json_trace_buffer, "members"); |
| + const intptr_t last = ring_start_ + ring_size_; |
| + for (intptr_t i = ring_start_; i < last; i++) { |
| + intptr_t index = RingIndex(i); |
| + const TraceBufferEntry& entry = ring_[index]; |
| + JSONObject trace_entry(&json_trace_buffer_array); |
| + trace_entry.AddProperty("type", "TraceBufferEntry"); |
| + 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.
|
| + trace_entry.AddProperty("message", entry.message); |
| + } |
| +} |
| + |
| +} // namespace dart |