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" |
11 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
12 #include "vm/message.h" | 12 #include "vm/message.h" |
13 #include "vm/object.h" | 13 #include "vm/object.h" |
14 #include "vm/object_id_ring.h" | 14 #include "vm/object_id_ring.h" |
15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
16 #include "vm/port.h" | 16 #include "vm/port.h" |
17 #include "vm/profiler.h" | |
17 | 18 |
18 namespace dart { | 19 namespace dart { |
19 | 20 |
20 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); | 21 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); |
21 | 22 |
22 struct ServiceMessageHandlerEntry { | 23 struct ServiceMessageHandlerEntry { |
23 const char* command; | 24 const char* command; |
24 ServiceMessageHandler handler; | 25 ServiceMessageHandler handler; |
25 }; | 26 }; |
26 | 27 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 PrintError(js, "Must specify collection object id: %s/id", collection); \ | 245 PrintError(js, "Must specify collection object id: %s/id", collection); \ |
245 return; \ | 246 return; \ |
246 } \ | 247 } \ |
247 if ((id < 0) || (id >= length)) { \ | 248 if ((id < 0) || (id >= length)) { \ |
248 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \ | 249 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \ |
249 length); \ | 250 length); \ |
250 return; \ | 251 return; \ |
251 } | 252 } |
252 | 253 |
253 | 254 |
254 static bool GetIntegerId(const char* s, intptr_t* id) { | 255 static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) { |
255 if ((s == NULL) || (*s == '\0')) { | 256 if ((s == NULL) || (*s == '\0')) { |
256 // Empty string. | 257 // Empty string. |
257 return false; | 258 return false; |
258 } | 259 } |
259 if (id == NULL) { | 260 if (id == NULL) { |
260 // No id pointer. | 261 // No id pointer. |
261 return false; | 262 return false; |
262 } | 263 } |
263 intptr_t r = 0; | 264 intptr_t r = 0; |
264 char* end_ptr = NULL; | 265 char* end_ptr = NULL; |
265 r = strtol(s, &end_ptr, 10); | 266 r = strtol(s, &end_ptr, base); |
266 if (end_ptr == s) { | 267 if (end_ptr == s) { |
267 // String was not advanced at all, cannot be valid. | 268 // String was not advanced at all, cannot be valid. |
268 return false; | 269 return false; |
270 } | |
271 *id = r; | |
272 return true; | |
273 } | |
274 | |
275 | |
276 static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) { | |
277 if ((s == NULL) || (*s == '\0')) { | |
278 // Empty string. | |
279 return false; | |
280 } | |
281 if (id == NULL) { | |
282 // No id pointer. | |
283 return false; | |
284 } | |
285 uintptr_t r = 0; | |
286 char* end_ptr = NULL; | |
287 r = strtoul(s, &end_ptr, base); | |
288 if (end_ptr == s) { | |
289 // String was not advanced at all, cannot be valid. | |
290 return false; | |
269 } | 291 } |
270 *id = r; | 292 *id = r; |
271 return true; | 293 return true; |
272 } | 294 } |
273 | 295 |
274 | 296 |
275 static void HandleClassesClosures(Isolate* isolate, const Class& cls, | 297 static void HandleClassesClosures(Isolate* isolate, const Class& cls, |
276 JSONStream* js) { | 298 JSONStream* js) { |
277 const GrowableObjectArray& closures = | 299 const GrowableObjectArray& closures = |
278 GrowableObjectArray::Handle(cls.closures()); | 300 GrowableObjectArray::Handle(cls.closures()); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 } | 536 } |
515 | 537 |
516 | 538 |
517 static void HandleCpu(Isolate* isolate, JSONStream* js) { | 539 static void HandleCpu(Isolate* isolate, JSONStream* js) { |
518 JSONObject jsobj(js); | 540 JSONObject jsobj(js); |
519 jsobj.AddProperty("type", "CPU"); | 541 jsobj.AddProperty("type", "CPU"); |
520 jsobj.AddProperty("architecture", CPU::Id()); | 542 jsobj.AddProperty("architecture", CPU::Id()); |
521 } | 543 } |
522 | 544 |
523 | 545 |
546 static void HandleCode(Isolate* isolate, JSONStream* js) { | |
547 REQUIRE_COLLECTION_ID("code"); | |
548 uintptr_t pc; | |
549 if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) { | |
550 PrintError(js, "Must specify code address: code/c0deadd0."); | |
551 return; | |
552 } | |
553 Code& code = Code::Handle(Code::LookupCode(pc)); | |
554 if (code.IsNull()) { | |
555 PrintError(js, "Could not find code at %" Px "", pc); | |
556 return; | |
557 } | |
558 code.PrintToJSONStream(js, false); | |
559 } | |
560 | |
561 | |
562 static void HandleProfile(Isolate* isolate, JSONStream* js) { | |
563 Profiler::PrintToJSONStream(isolate, js); | |
564 } | |
565 | |
566 | |
524 static ServiceMessageHandlerEntry __message_handlers[] = { | 567 static ServiceMessageHandlerEntry __message_handlers[] = { |
525 { "_echo", HandleEcho }, | 568 { "_echo", HandleEcho }, |
526 { "classes", HandleClasses }, | 569 { "classes", HandleClasses }, |
570 { "code", HandleCode }, | |
527 { "cpu", HandleCpu }, | 571 { "cpu", HandleCpu }, |
528 { "debug", HandleDebug }, | 572 { "debug", HandleDebug }, |
529 { "libraries", HandleLibraries }, | 573 { "libraries", HandleLibraries }, |
530 { "library", HandleLibrary }, | 574 { "library", HandleLibrary }, |
531 { "name", HandleName }, | 575 { "name", HandleName }, |
532 { "objecthistogram", HandleObjectHistogram}, | 576 { "objecthistogram", HandleObjectHistogram}, |
533 { "objects", HandleObjects }, | 577 { "objects", HandleObjects }, |
578 { "profile", HandleProfile }, | |
Ivan Posva
2013/12/30 23:06:09
We will want to separate profile from profile tick
| |
534 { "scripts", HandleScripts }, | 579 { "scripts", HandleScripts }, |
535 { "stacktrace", HandleStackTrace }, | 580 { "stacktrace", HandleStackTrace }, |
536 }; | 581 }; |
537 | 582 |
538 | 583 |
539 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { | 584 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
540 JSONObject jsobj(js); | 585 JSONObject jsobj(js); |
541 jsobj.AddProperty("type", "Error"); | 586 jsobj.AddProperty("type", "Error"); |
542 jsobj.AddProperty("text", "request not understood."); | 587 jsobj.AddProperty("text", "request not understood."); |
543 PrintArgumentsAndOptions(jsobj, js); | 588 PrintArgumentsAndOptions(jsobj, js); |
544 } | 589 } |
545 | 590 |
546 | 591 |
547 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 592 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
548 intptr_t num_message_handlers = sizeof(__message_handlers) / | 593 intptr_t num_message_handlers = sizeof(__message_handlers) / |
549 sizeof(__message_handlers[0]); | 594 sizeof(__message_handlers[0]); |
550 for (intptr_t i = 0; i < num_message_handlers; i++) { | 595 for (intptr_t i = 0; i < num_message_handlers; i++) { |
551 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 596 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
552 if (!strcmp(command, entry.command)) { | 597 if (!strcmp(command, entry.command)) { |
553 return entry.handler; | 598 return entry.handler; |
554 } | 599 } |
555 } | 600 } |
556 return HandleFallthrough; | 601 return HandleFallthrough; |
557 } | 602 } |
558 | 603 |
559 } // namespace dart | 604 } // namespace dart |
OLD | NEW |