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 |