Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 #include "vm/isolate.h" | 5 #include "vm/isolate.h" |
| 6 #include "vm/json_stream.h" | 6 #include "vm/json_stream.h" |
| 7 #include "vm/object.h" | |
| 7 #include "vm/os.h" | 8 #include "vm/os.h" |
| 8 #include "vm/trace_buffer.h" | 9 #include "vm/trace_buffer.h" |
| 9 | 10 |
| 10 namespace dart { | 11 namespace dart { |
| 11 | 12 |
| 12 TraceBuffer::TraceBuffer(Isolate* isolate, intptr_t capacity) | 13 TraceBuffer::TraceBuffer(Isolate* isolate, intptr_t capacity) |
| 13 : isolate_(isolate), ring_capacity_(capacity) { | 14 : isolate_(isolate), ring_capacity_(capacity) { |
| 14 ring_cursor_ = 0; | 15 ring_cursor_ = 0; |
| 15 ring_ = reinterpret_cast<TraceBufferEntry*>( | 16 ring_ = reinterpret_cast<TraceBufferEntry*>( |
| 16 calloc(ring_capacity_, sizeof(TraceBufferEntry))); // NOLINT | 17 calloc(ring_capacity_, sizeof(TraceBufferEntry))); // NOLINT |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 33 isolate->set_trace_buffer(trace_buffer); | 34 isolate->set_trace_buffer(trace_buffer); |
| 34 } | 35 } |
| 35 | 36 |
| 36 | 37 |
| 37 void TraceBuffer::Clear() { | 38 void TraceBuffer::Clear() { |
| 38 for (intptr_t i = 0; i < ring_capacity_; i++) { | 39 for (intptr_t i = 0; i < ring_capacity_; i++) { |
| 39 TraceBufferEntry& entry = ring_[i]; | 40 TraceBufferEntry& entry = ring_[i]; |
| 40 entry.micros = 0; | 41 entry.micros = 0; |
| 41 free(entry.message); | 42 free(entry.message); |
| 42 entry.message = NULL; | 43 entry.message = NULL; |
| 44 entry.message_is_escaped = false; | |
| 43 } | 45 } |
| 44 ring_cursor_ = 0; | 46 ring_cursor_ = 0; |
| 45 } | 47 } |
| 46 | 48 |
| 47 | 49 |
| 48 void TraceBuffer::Fill(TraceBufferEntry* entry, int64_t micros, char* msg) { | 50 void TraceBuffer::Fill(TraceBufferEntry* entry, int64_t micros, |
| 51 char* msg, bool msg_is_escaped) { | |
| 49 if (entry->message != NULL) { | 52 if (entry->message != NULL) { |
| 50 // Recycle TraceBufferEntry. | 53 // Recycle TraceBufferEntry. |
| 51 free(entry->message); | 54 free(entry->message); |
| 52 } | 55 } |
| 53 entry->message = msg; | 56 entry->message = msg; |
| 57 entry->message_is_escaped = msg_is_escaped; | |
| 54 entry->micros = micros; | 58 entry->micros = micros; |
| 55 } | 59 } |
| 56 | 60 |
| 57 | 61 |
| 58 void TraceBuffer::AppendTrace(int64_t micros, char* message) { | 62 void TraceBuffer::AppendTrace(int64_t micros, char* msg, bool msg_is_escaped) { |
| 59 const intptr_t index = ring_cursor_; | 63 const intptr_t index = ring_cursor_; |
| 60 TraceBufferEntry* trace_entry = &ring_[index]; | 64 TraceBufferEntry* trace_entry = &ring_[index]; |
| 61 Fill(trace_entry, micros, message); | 65 Fill(trace_entry, micros, msg, msg_is_escaped); |
| 62 ring_cursor_ = RingIndex(ring_cursor_ + 1); | 66 ring_cursor_ = RingIndex(ring_cursor_ + 1); |
| 63 } | 67 } |
| 64 | 68 |
| 65 | 69 |
| 66 void TraceBuffer::Trace(int64_t micros, const char* message) { | 70 void TraceBuffer::Trace(int64_t micros, const char* msg, bool msg_is_escaped) { |
| 67 ASSERT(message != NULL); | 71 ASSERT(msg != NULL); |
| 68 char* message_copy = strdup(message); | 72 char* message_copy = strdup(msg); |
| 69 AppendTrace(micros, message_copy); | 73 AppendTrace(micros, message_copy, msg_is_escaped); |
| 70 } | 74 } |
| 71 | 75 |
| 72 | 76 |
| 73 void TraceBuffer::Trace(const char* message) { | 77 void TraceBuffer::Trace(const char* msg, bool msg_is_escaped) { |
| 74 Trace(OS::GetCurrentTimeMicros(), message); | 78 Trace(OS::GetCurrentTimeMicros(), msg, msg_is_escaped); |
| 75 } | 79 } |
| 76 | 80 |
| 77 | 81 |
| 78 void TraceBuffer::TraceF(const char* format, ...) { | 82 void TraceBuffer::TraceF(const char* format, ...) { |
| 79 int64_t micros = OS::GetCurrentTimeMicros(); | 83 const int64_t micros = OS::GetCurrentTimeMicros(); |
| 80 va_list args; | 84 va_list args; |
| 81 va_start(args, format); | 85 va_start(args, format); |
| 82 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 86 const intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 83 va_end(args); | 87 va_end(args); |
| 84 char* p = reinterpret_cast<char*>(malloc(len+1)); | 88 char* p = reinterpret_cast<char*>(malloc(len+1)); |
| 85 va_start(args, format); | 89 va_start(args, format); |
| 86 intptr_t len2 = OS::VSNPrint(p, len+1, format, args); | 90 const intptr_t len2 = OS::VSNPrint(p, len+1, format, args); |
| 87 va_end(args); | 91 va_end(args); |
| 88 ASSERT(len == len2); | 92 ASSERT(len == len2); |
| 89 AppendTrace(micros, p); | 93 AppendTrace(micros, p); |
| 90 } | 94 } |
| 91 | 95 |
| 92 | 96 |
| 97 void TraceBuffer::TraceWarningF(Isolate* isolate, | |
| 98 const Script& script, intptr_t token_pos, | |
| 99 const char* format, ...) { | |
| 100 va_list args; | |
| 101 va_start(args, format); | |
| 102 TraceWarningV(isolate, script, token_pos, format, args); | |
| 103 va_end(args); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 void TraceBuffer::TraceWarningV(Isolate* isolate, | |
| 108 const Script& script, intptr_t token_pos, | |
| 109 const char* format, va_list args) { | |
| 110 const int64_t micros = OS::GetCurrentTimeMicros(); | |
| 111 TraceBuffer* trace_buffer = isolate->trace_buffer(); | |
| 112 if (trace_buffer == NULL) { | |
| 113 Init(isolate); | |
| 114 trace_buffer = isolate->trace_buffer(); | |
| 115 } | |
| 116 JSONStream js; | |
| 117 { | |
| 118 JSONObject trace_warning(&js); | |
| 119 trace_warning.AddProperty("type", "Warning"); | |
|
Cutch
2014/06/12 21:09:05
Please use a different type than "Warning". We wil
regis
2014/06/13 00:04:37
I've called it JSCompatibilityWarning for now.
A l
| |
| 120 trace_warning.AddProperty("script", script); | |
| 121 trace_warning.AddProperty("tokenPos", token_pos); | |
| 122 va_list args_copy; | |
| 123 va_copy(args_copy, args); | |
| 124 const intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); | |
| 125 va_end(args_copy); | |
| 126 char* msg = reinterpret_cast<char*>(malloc(len + 1)); | |
| 127 va_copy(args_copy, args); | |
| 128 OS::VSNPrint(msg, len + 1, format, args_copy); | |
| 129 va_end(args_copy); | |
| 130 trace_warning.AddProperty("message", msg); | |
| 131 } | |
| 132 trace_buffer->Trace(micros, js.ToCString(), true); // Already escaped. | |
| 133 } | |
| 134 | |
| 135 | |
| 93 void TraceBuffer::PrintToJSONStream(JSONStream* stream) const { | 136 void TraceBuffer::PrintToJSONStream(JSONStream* stream) const { |
| 94 JSONObject json_trace_buffer(stream); | 137 JSONObject json_trace_buffer(stream); |
| 95 json_trace_buffer.AddProperty("type", "TraceBuffer"); | 138 json_trace_buffer.AddProperty("type", "TraceBuffer"); |
| 96 // TODO(johnmccutchan): Send cursor position in response. | 139 // TODO(johnmccutchan): Send cursor position in response. |
| 97 JSONArray json_trace_buffer_array(&json_trace_buffer, "members"); | 140 JSONArray json_trace_buffer_array(&json_trace_buffer, "members"); |
| 98 // Scan forward until we find the first entry which isn't empty. | 141 // Scan forward until we find the first entry which isn't empty. |
| 99 // TODO(johnmccutchan): Accept cursor start position as input. | 142 // TODO(johnmccutchan): Accept cursor start position as input. |
| 100 intptr_t start = -1; | 143 intptr_t start = -1; |
| 101 for (intptr_t i = 0; i < ring_capacity_; i++) { | 144 for (intptr_t i = 0; i < ring_capacity_; i++) { |
| 102 intptr_t index = RingIndex(i + ring_cursor_); | 145 intptr_t index = RingIndex(i + ring_cursor_); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 114 const TraceBufferEntry& entry = ring_[index]; | 157 const TraceBufferEntry& entry = ring_[index]; |
| 115 if (entry.empty()) { | 158 if (entry.empty()) { |
| 116 // Empty entry, stop. | 159 // Empty entry, stop. |
| 117 break; | 160 break; |
| 118 } | 161 } |
| 119 JSONObject trace_entry(&json_trace_buffer_array); | 162 JSONObject trace_entry(&json_trace_buffer_array); |
| 120 trace_entry.AddProperty("type", "TraceBufferEntry"); | 163 trace_entry.AddProperty("type", "TraceBufferEntry"); |
| 121 double seconds = static_cast<double>(entry.micros) / | 164 double seconds = static_cast<double>(entry.micros) / |
| 122 static_cast<double>(kMicrosecondsPerSecond); | 165 static_cast<double>(kMicrosecondsPerSecond); |
| 123 trace_entry.AddProperty("time", seconds); | 166 trace_entry.AddProperty("time", seconds); |
| 124 trace_entry.AddProperty("message", entry.message); | 167 if (entry.message_is_escaped) { |
| 168 trace_entry.AddPropertyNoEscape("message", entry.message); | |
| 169 } else { | |
| 170 trace_entry.AddProperty("message", entry.message); | |
| 171 } | |
| 125 } | 172 } |
| 126 } | 173 } |
| 127 | 174 |
| 128 } // namespace dart | 175 } // namespace dart |
| OLD | NEW |