| 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/service.h" | 5 #include "vm/service.h" |
| 6 | 6 |
| 7 #include "vm/cpu.h" | 7 #include "vm/cpu.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
| 10 #include "vm/heap_histogram.h" | 10 #include "vm/heap_histogram.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } | 146 } |
| 147 { | 147 { |
| 148 JSONArray jsarr(&jsobj, "option_values"); | 148 JSONArray jsarr(&jsobj, "option_values"); |
| 149 for (intptr_t i = 0; i < js->num_options(); i++) { | 149 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 150 jsarr.AddValue(js->GetOptionValue(i)); | 150 jsarr.AddValue(js->GetOptionValue(i)); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 static void PrintCollectionErrorResponse(const char* collection_name, | |
| 157 JSONStream* js) { | |
| 158 JSONObject jsobj(js); | |
| 159 jsobj.AddProperty("type", "error"); | |
| 160 jsobj.AddPropertyF("text", "Must specify collection object id: /%s/id", | |
| 161 collection_name); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 static void PrintGenericError(JSONStream* js) { | 156 static void PrintGenericError(JSONStream* js) { |
| 166 JSONObject jsobj(js); | 157 JSONObject jsobj(js); |
| 167 jsobj.AddProperty("type", "error"); | 158 jsobj.AddProperty("type", "Error"); |
| 168 jsobj.AddProperty("text", "Invalid request."); | 159 jsobj.AddProperty("text", "Invalid request."); |
| 169 PrintArgumentsAndOptions(jsobj, js); | 160 PrintArgumentsAndOptions(jsobj, js); |
| 170 } | 161 } |
| 171 | 162 |
| 163 |
| 164 static void PrintError(JSONStream* js, const char* format, ...) { |
| 165 Isolate* isolate = Isolate::Current(); |
| 166 |
| 167 va_list args; |
| 168 va_start(args, format); |
| 169 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 170 va_end(args); |
| 171 |
| 172 char* buffer = isolate->current_zone()->Alloc<char>(len + 1); |
| 173 va_list args2; |
| 174 va_start(args2, format); |
| 175 OS::VSNPrint(buffer, (len + 1), format, args2); |
| 176 va_end(args2); |
| 177 |
| 178 JSONObject jsobj(js); |
| 179 jsobj.AddProperty("type", "Error"); |
| 180 jsobj.AddProperty("text", buffer); |
| 181 PrintArgumentsAndOptions(jsobj, js); |
| 182 } |
| 183 |
| 172 | 184 |
| 173 static void HandleName(Isolate* isolate, JSONStream* js) { | 185 static void HandleName(Isolate* isolate, JSONStream* js) { |
| 174 JSONObject jsobj(js); | 186 JSONObject jsobj(js); |
| 175 jsobj.AddProperty("type", "IsolateName"); | 187 jsobj.AddProperty("type", "IsolateName"); |
| 176 jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); | 188 jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); |
| 177 jsobj.AddProperty("name", isolate->name()); | 189 jsobj.AddProperty("name", isolate->name()); |
| 178 } | 190 } |
| 179 | 191 |
| 180 | 192 |
| 181 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { | 193 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 197 jsobj.AddProperty("function", frame->function()); | 209 jsobj.AddProperty("function", frame->function()); |
| 198 jsobj.AddProperty("code", frame->code()); | 210 jsobj.AddProperty("code", frame->code()); |
| 199 } | 211 } |
| 200 } | 212 } |
| 201 | 213 |
| 202 | 214 |
| 203 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { | 215 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { |
| 204 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); | 216 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); |
| 205 if (histogram == NULL) { | 217 if (histogram == NULL) { |
| 206 JSONObject jsobj(js); | 218 JSONObject jsobj(js); |
| 207 jsobj.AddProperty("type", "error"); | 219 jsobj.AddProperty("type", "Error"); |
| 208 jsobj.AddProperty("text", "Run with --print_object_histogram"); | 220 jsobj.AddProperty("text", "Run with --print_object_histogram"); |
| 209 return; | 221 return; |
| 210 } | 222 } |
| 211 histogram->PrintToJSONStream(js); | 223 histogram->PrintToJSONStream(js); |
| 212 } | 224 } |
| 213 | 225 |
| 214 | 226 |
| 215 static void HandleEcho(Isolate* isolate, JSONStream* js) { | 227 static void HandleEcho(Isolate* isolate, JSONStream* js) { |
| 216 JSONObject jsobj(js); | 228 JSONObject jsobj(js); |
| 217 jsobj.AddProperty("type", "message"); | 229 jsobj.AddProperty("type", "message"); |
| 218 PrintArgumentsAndOptions(jsobj, js); | 230 PrintArgumentsAndOptions(jsobj, js); |
| 219 } | 231 } |
| 220 | 232 |
| 221 | 233 |
| 222 // Print an error message if there is no ID argument. | 234 // Print an error message if there is no ID argument. |
| 223 #define REQUIRE_COLLECTION_ID(collection) \ | 235 #define REQUIRE_COLLECTION_ID(collection) \ |
| 224 if (js->num_arguments() == 1) { \ | 236 if (js->num_arguments() == 1) { \ |
| 225 PrintCollectionErrorResponse(collection, js); \ | 237 PrintError(js, "Must specify collection object id: /%s/id", collection); \ |
| 226 return; \ | 238 return; \ |
| 227 } | 239 } |
| 228 | 240 |
| 229 | 241 |
| 230 static void HandleClasses(Isolate* isolate, JSONStream* js) { | 242 static void HandleClasses(Isolate* isolate, JSONStream* js) { |
| 231 if (js->num_arguments() == 1) { | 243 if (js->num_arguments() == 1) { |
| 232 ClassTable* table = isolate->class_table(); | 244 ClassTable* table = isolate->class_table(); |
| 233 table->PrintToJSONStream(js); | 245 table->PrintToJSONStream(js); |
| 234 return; | 246 return; |
| 235 } | 247 } |
| 236 ASSERT(js->num_arguments() >= 2); | 248 ASSERT(js->num_arguments() >= 2); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 260 REQUIRE_COLLECTION_ID("objects"); | 272 REQUIRE_COLLECTION_ID("objects"); |
| 261 ASSERT(js->num_arguments() >= 2); | 273 ASSERT(js->num_arguments() >= 2); |
| 262 ObjectIdRing* ring = isolate->object_id_ring(); | 274 ObjectIdRing* ring = isolate->object_id_ring(); |
| 263 ASSERT(ring != NULL); | 275 ASSERT(ring != NULL); |
| 264 intptr_t id = atoi(js->GetArgument(1)); | 276 intptr_t id = atoi(js->GetArgument(1)); |
| 265 Object& obj = Object::Handle(ring->GetObjectForId(id)); | 277 Object& obj = Object::Handle(ring->GetObjectForId(id)); |
| 266 obj.PrintToJSONStream(js, false); | 278 obj.PrintToJSONStream(js, false); |
| 267 } | 279 } |
| 268 | 280 |
| 269 | 281 |
| 282 static void HandleDebug(Isolate* isolate, JSONStream* js) { |
| 283 if (js->num_arguments() == 1) { |
| 284 PrintError(js, "Must specify a subcommand"); |
| 285 return; |
| 286 } |
| 287 const char* command = js->GetArgument(1); |
| 288 if (!strcmp(command, "breakpoints")) { |
| 289 if (js->num_arguments() == 2) { |
| 290 // Print breakpoint list. |
| 291 JSONObject jsobj(js); |
| 292 jsobj.AddProperty("type", "BreakpointList"); |
| 293 JSONArray jsarr(&jsobj, "breakpoints"); |
| 294 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr); |
| 295 |
| 296 } else if (js->num_arguments() == 3) { |
| 297 // Print individual breakpoint. |
| 298 intptr_t id = atoi(js->GetArgument(2)); |
| 299 SourceBreakpoint* bpt = isolate->debugger()->GetBreakpointById(id); |
| 300 if (bpt != NULL) { |
| 301 bpt->PrintToJSONStream(js); |
| 302 } else { |
| 303 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2)); |
| 304 } |
| 305 |
| 306 } else { |
| 307 PrintError(js, "Command too long"); |
| 308 } |
| 309 } else { |
| 310 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); |
| 311 } |
| 312 } |
| 313 |
| 314 |
| 270 static void HandleCpu(Isolate* isolate, JSONStream* js) { | 315 static void HandleCpu(Isolate* isolate, JSONStream* js) { |
| 271 JSONObject jsobj(js); | 316 JSONObject jsobj(js); |
| 272 jsobj.AddProperty("type", "CPU"); | 317 jsobj.AddProperty("type", "CPU"); |
| 273 jsobj.AddProperty("architecture", CPU::Id()); | 318 jsobj.AddProperty("architecture", CPU::Id()); |
| 274 } | 319 } |
| 275 | 320 |
| 276 | 321 |
| 277 // Alphabetical order. | |
| 278 static ServiceMessageHandlerEntry __message_handlers[] = { | 322 static ServiceMessageHandlerEntry __message_handlers[] = { |
| 279 { "_echo", HandleEcho }, | 323 { "_echo", HandleEcho }, |
| 280 { "classes", HandleClasses }, | 324 { "classes", HandleClasses }, |
| 281 { "cpu", HandleCpu }, | 325 { "cpu", HandleCpu }, |
| 326 { "debug", HandleDebug }, |
| 282 { "library", HandleLibrary }, | 327 { "library", HandleLibrary }, |
| 283 { "name", HandleName }, | 328 { "name", HandleName }, |
| 284 { "objecthistogram", HandleObjectHistogram}, | 329 { "objecthistogram", HandleObjectHistogram}, |
| 285 { "objects", HandleObjects }, | 330 { "objects", HandleObjects }, |
| 286 { "stacktrace", HandleStackTrace }, | 331 { "stacktrace", HandleStackTrace }, |
| 287 }; | 332 }; |
| 288 | 333 |
| 289 | 334 |
| 290 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { | 335 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
| 291 JSONObject jsobj(js); | 336 JSONObject jsobj(js); |
| 292 jsobj.AddProperty("type", "error"); | 337 jsobj.AddProperty("type", "Error"); |
| 293 jsobj.AddProperty("text", "request not understood."); | 338 jsobj.AddProperty("text", "request not understood."); |
| 294 PrintArgumentsAndOptions(jsobj, js); | 339 PrintArgumentsAndOptions(jsobj, js); |
| 295 } | 340 } |
| 296 | 341 |
| 297 | 342 |
| 298 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 343 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
| 299 intptr_t num_message_handlers = sizeof(__message_handlers) / | 344 intptr_t num_message_handlers = sizeof(__message_handlers) / |
| 300 sizeof(__message_handlers[0]); | 345 sizeof(__message_handlers[0]); |
| 301 for (intptr_t i = 0; i < num_message_handlers; i++) { | 346 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 302 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 347 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
| 303 if (!strcmp(command, entry.command)) { | 348 if (!strcmp(command, entry.command)) { |
| 304 return entry.handler; | 349 return entry.handler; |
| 305 } | 350 } |
| 306 } | 351 } |
| 307 return HandleFallthrough; | 352 return HandleFallthrough; |
| 308 } | 353 } |
| 309 | 354 |
| 310 } // namespace dart | 355 } // namespace dart |
| OLD | NEW |