| 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/debugger.h" | 5 #include "vm/debugger.h" |
| 6 #include "vm/heap_histogram.h" | 6 #include "vm/heap_histogram.h" |
| 7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 8 #include "vm/message.h" | 8 #include "vm/message.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/port.h" | 10 #include "vm/port.h" |
| 11 #include "vm/service.h" | 11 #include "vm/service.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 typedef RawString* (*ServiceMessageHandler)(Isolate* isolate); | 15 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); |
| 16 | 16 |
| 17 struct ServiceMessageHandlerEntry { | 17 struct ServiceMessageHandlerEntry { |
| 18 const char* command; | 18 const char* command; |
| 19 ServiceMessageHandler handler; | 19 ServiceMessageHandler handler; |
| 20 }; | 20 }; |
| 21 | 21 |
| 22 static ServiceMessageHandler FindServiceMessageHandler(const char* command); | 22 static ServiceMessageHandler FindServiceMessageHandler(const char* command); |
| 23 | 23 |
| 24 | 24 |
| 25 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 25 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 ASSERT(path.Length() > 0); | 66 ASSERT(path.Length() > 0); |
| 67 // Same number of option keys as values. | 67 // Same number of option keys as values. |
| 68 ASSERT(option_keys.Length() == option_values.Length()); | 68 ASSERT(option_keys.Length() == option_values.Length()); |
| 69 | 69 |
| 70 String& pathSegment = String::Handle(); | 70 String& pathSegment = String::Handle(); |
| 71 pathSegment ^= path.At(0); | 71 pathSegment ^= path.At(0); |
| 72 ASSERT(!pathSegment.IsNull()); | 72 ASSERT(!pathSegment.IsNull()); |
| 73 | 73 |
| 74 ServiceMessageHandler handler = | 74 ServiceMessageHandler handler = |
| 75 FindServiceMessageHandler(pathSegment.ToCString()); | 75 FindServiceMessageHandler(pathSegment.ToCString()); |
| 76 String& reply = String::Handle(); | 76 ASSERT(handler != NULL); |
| 77 reply ^= handler(isolate); | 77 { |
| 78 ASSERT(!reply.IsNull()); | 78 TextBuffer buffer(256); |
| 79 PostReply(reply, reply_port); | 79 JSONStream js(&buffer); |
| 80 |
| 81 // Setup JSONStream arguments and options. The arguments and options |
| 82 // are zone allocated and will be freed immediately after handling the |
| 83 // message. |
| 84 Zone* zoneAllocator = zone.GetZone(); |
| 85 const char** arguments = zoneAllocator->Alloc<const char*>(path.Length()); |
| 86 String& string_iterator = String::Handle(); |
| 87 for (intptr_t i = 0; i < path.Length(); i++) { |
| 88 string_iterator ^= path.At(i); |
| 89 arguments[i] = |
| 90 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); |
| 91 } |
| 92 js.SetArguments(arguments, path.Length()); |
| 93 if (option_keys.Length() > 0) { |
| 94 const char** option_keys_native = |
| 95 zoneAllocator->Alloc<const char*>(option_keys.Length()); |
| 96 const char** option_values_native = |
| 97 zoneAllocator->Alloc<const char*>(option_keys.Length()); |
| 98 for (intptr_t i = 0; i < option_keys.Length(); i++) { |
| 99 string_iterator ^= option_keys.At(i); |
| 100 option_keys_native[i] = |
| 101 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); |
| 102 string_iterator ^= option_values.At(i); |
| 103 option_values_native[i] = |
| 104 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); |
| 105 } |
| 106 js.SetOptions(option_keys_native, option_values_native, |
| 107 option_keys.Length()); |
| 108 } |
| 109 |
| 110 handler(isolate, &js); |
| 111 const String& reply = String::Handle(String::New(buffer.buf())); |
| 112 ASSERT(!reply.IsNull()); |
| 113 PostReply(reply, reply_port); |
| 114 } |
| 80 } | 115 } |
| 81 } | 116 } |
| 82 | 117 |
| 83 | 118 |
| 84 static RawString* HandleName(Isolate* isolate) { | 119 static void HandleName(Isolate* isolate, JSONStream* js) { |
| 85 TextBuffer buffer(256); | 120 js->OpenObject(); |
| 86 JSONStream js(&buffer); | 121 js->PrintProperty("type", "IsolateName"); |
| 87 js.OpenObject(); | 122 js->PrintProperty("id", static_cast<intptr_t>(isolate->main_port())); |
| 88 js.PrintProperty("type", "IsolateName"); | 123 js->PrintProperty("name", isolate->name()); |
| 89 js.PrintProperty("id", static_cast<intptr_t>(isolate->main_port())); | 124 js->CloseObject(); |
| 90 js.PrintProperty("name", isolate->name()); | |
| 91 js.CloseObject(); | |
| 92 return String::New(buffer.buf()); | |
| 93 } | 125 } |
| 94 | 126 |
| 95 | 127 |
| 96 RawString* HandleStackTrace(Isolate* isolate) { | 128 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { |
| 97 TextBuffer buffer(256); | |
| 98 JSONStream js(&buffer); | |
| 99 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 129 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
| 100 js.OpenObject(); | 130 js->OpenObject(); |
| 101 js.PrintProperty("type", "StackTrace"); | 131 js->PrintProperty("type", "StackTrace"); |
| 102 js.OpenArray("members"); | 132 js->OpenArray("members"); |
| 103 intptr_t n_frames = stack->Length(); | 133 intptr_t n_frames = stack->Length(); |
| 104 String& url = String::Handle(); | 134 String& url = String::Handle(); |
| 105 String& function = String::Handle(); | 135 String& function = String::Handle(); |
| 106 for (int i = 0; i < n_frames; i++) { | 136 for (int i = 0; i < n_frames; i++) { |
| 107 ActivationFrame* frame = stack->ActivationFrameAt(i); | 137 ActivationFrame* frame = stack->ActivationFrameAt(i); |
| 108 url ^= frame->SourceUrl(); | 138 url ^= frame->SourceUrl(); |
| 109 function ^= frame->function().UserVisibleName(); | 139 function ^= frame->function().UserVisibleName(); |
| 110 js.OpenObject(); | 140 js->OpenObject(); |
| 111 js.PrintProperty("name", function.ToCString()); | 141 js->PrintProperty("name", function.ToCString()); |
| 112 js.PrintProperty("url", url.ToCString()); | 142 js->PrintProperty("url", url.ToCString()); |
| 113 js.PrintProperty("line", frame->LineNumber()); | 143 js->PrintProperty("line", frame->LineNumber()); |
| 114 js.PrintProperty("function", frame->function()); | 144 js->PrintProperty("function", frame->function()); |
| 115 js.PrintProperty("code", frame->code()); | 145 js->PrintProperty("code", frame->code()); |
| 116 js.CloseObject(); | 146 js->CloseObject(); |
| 117 } | 147 } |
| 118 js.CloseArray(); | 148 js->CloseArray(); |
| 119 js.CloseObject(); | 149 js->CloseObject(); |
| 120 return String::New(buffer.buf()); | |
| 121 } | 150 } |
| 122 | 151 |
| 123 | 152 |
| 124 RawString* HandleObjectHistogram(Isolate* isolate) { | 153 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { |
| 125 TextBuffer buffer(256); | |
| 126 JSONStream js(&buffer); | |
| 127 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); | 154 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); |
| 128 if (histogram == NULL) { | 155 if (histogram == NULL) { |
| 129 js.OpenObject(); | 156 js->OpenObject(); |
| 130 js.PrintProperty("type", "ObjectHistogram"); | 157 js->PrintProperty("type", "ObjectHistogram"); |
| 131 js.PrintProperty("error", "Run with --print_object_histogram"); | 158 js->PrintProperty("error", "Run with --print_object_histogram"); |
| 132 js.CloseObject(); | 159 js->CloseObject(); |
| 133 return String::New(buffer.buf()); | 160 return; |
| 134 } | 161 } |
| 135 histogram->PrintToJSONStream(&js); | 162 histogram->PrintToJSONStream(js); |
| 136 return String::New(buffer.buf()); | |
| 137 } | 163 } |
| 138 | 164 |
| 139 | 165 |
| 166 static void PrintArgumentsAndOptions(JSONStream* js) { |
| 167 js->OpenObject("message"); |
| 168 js->OpenArray("arguments"); |
| 169 for (intptr_t i = 0; i < js->num_arguments(); i++) { |
| 170 js->PrintValue(js->GetArgument(i)); |
| 171 } |
| 172 js->CloseArray(); |
| 173 js->OpenArray("option_keys"); |
| 174 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 175 js->PrintValue(js->GetOptionKey(i)); |
| 176 } |
| 177 js->CloseArray(); |
| 178 js->OpenArray("option_values"); |
| 179 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 180 js->PrintValue(js->GetOptionValue(i)); |
| 181 } |
| 182 js->CloseArray(); |
| 183 js->CloseObject(); |
| 184 } |
| 185 |
| 186 |
| 187 static void HandleEcho(Isolate* isolate, JSONStream* js) { |
| 188 js->OpenObject(); |
| 189 js->PrintProperty("type", "message"); |
| 190 PrintArgumentsAndOptions(js); |
| 191 js->CloseObject(); |
| 192 } |
| 193 |
| 194 |
| 140 static ServiceMessageHandlerEntry __message_handlers[] = { | 195 static ServiceMessageHandlerEntry __message_handlers[] = { |
| 141 { "name", HandleName }, | 196 { "name", HandleName }, |
| 142 { "stacktrace", HandleStackTrace }, | 197 { "stacktrace", HandleStackTrace }, |
| 143 { "objecthistogram", HandleObjectHistogram}, | 198 { "objecthistogram", HandleObjectHistogram}, |
| 199 { "_echo", HandleEcho }, |
| 144 }; | 200 }; |
| 145 | 201 |
| 146 | 202 |
| 147 static RawString* HandleFallthrough(Isolate* isolate) { | 203 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
| 148 TextBuffer buffer(256); | 204 js->OpenObject(); |
| 149 JSONStream js(&buffer); | 205 js->PrintProperty("type", "error"); |
| 150 js.OpenObject(); | 206 js->PrintProperty("text", "request not understood."); |
| 151 js.PrintProperty("type", "error"); | 207 PrintArgumentsAndOptions(js); |
| 152 js.PrintProperty("text", "request not supported."); | 208 js->CloseObject(); |
| 153 js.CloseObject(); | |
| 154 return String::New(buffer.buf()); | |
| 155 } | 209 } |
| 156 | 210 |
| 157 | 211 |
| 158 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 212 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
| 159 intptr_t num_message_handlers = sizeof(__message_handlers) / | 213 intptr_t num_message_handlers = sizeof(__message_handlers) / |
| 160 sizeof(__message_handlers[0]); | 214 sizeof(__message_handlers[0]); |
| 161 for (intptr_t i = 0; i < num_message_handlers; i++) { | 215 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 162 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 216 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
| 163 if (!strcmp(command, entry.command)) { | 217 if (!strcmp(command, entry.command)) { |
| 164 return entry.handler; | 218 return entry.handler; |
| 165 } | 219 } |
| 166 } | 220 } |
| 167 return HandleFallthrough; | 221 return HandleFallthrough; |
| 168 } | 222 } |
| 169 | 223 |
| 170 } // namespace dart | 224 } // namespace dart |
| OLD | NEW |