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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/coverage.h" | 10 #include "vm/coverage.h" |
11 #include "vm/cpu.h" | 11 #include "vm/cpu.h" |
12 #include "vm/dart_api_impl.h" | 12 #include "vm/dart_api_impl.h" |
13 #include "vm/dart_entry.h" | 13 #include "vm/dart_entry.h" |
14 #include "vm/debugger.h" | 14 #include "vm/debugger.h" |
15 #include "vm/isolate.h" | 15 #include "vm/isolate.h" |
16 #include "vm/message.h" | 16 #include "vm/message.h" |
17 #include "vm/message_handler.h" | 17 #include "vm/message_handler.h" |
18 #include "vm/native_entry.h" | 18 #include "vm/native_entry.h" |
19 #include "vm/native_arguments.h" | 19 #include "vm/native_arguments.h" |
20 #include "vm/object.h" | 20 #include "vm/object.h" |
21 #include "vm/object_id_ring.h" | 21 #include "vm/object_id_ring.h" |
22 #include "vm/object_store.h" | 22 #include "vm/object_store.h" |
23 #include "vm/port.h" | 23 #include "vm/port.h" |
24 #include "vm/profiler.h" | 24 #include "vm/profiler.h" |
25 #include "vm/stack_frame.h" | 25 #include "vm/stack_frame.h" |
26 #include "vm/symbols.h" | 26 #include "vm/symbols.h" |
| 27 #include "vm/version.h" |
27 | 28 |
28 | 29 |
29 namespace dart { | 30 namespace dart { |
30 | 31 |
31 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); | 32 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); |
32 | 33 |
33 struct ResourcesEntry { | 34 struct ResourcesEntry { |
34 const char* path_; | 35 const char* path_; |
35 const char* resource_; | 36 const char* resource_; |
36 int length_; | 37 int length_; |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 // TODO(johnmccutchan): Support asynchronous replies. | 628 // TODO(johnmccutchan): Support asynchronous replies. |
628 js.PostReply(); | 629 js.PostReply(); |
629 } | 630 } |
630 } | 631 } |
631 } | 632 } |
632 } | 633 } |
633 } | 634 } |
634 | 635 |
635 | 636 |
636 static bool HandleIsolate(Isolate* isolate, JSONStream* js) { | 637 static bool HandleIsolate(Isolate* isolate, JSONStream* js) { |
637 isolate->PrintToJSONStream(js); | 638 isolate->PrintToJSONStream(js, false); |
638 return true; | 639 return true; |
639 } | 640 } |
640 | 641 |
641 | 642 |
642 static bool HandleStackTrace(Isolate* isolate, JSONStream* js) { | 643 static bool HandleStackTrace(Isolate* isolate, JSONStream* js) { |
643 if (js->num_arguments() > 1) { | 644 if (js->num_arguments() > 1) { |
644 PrintError(js, "Command too long"); | 645 PrintError(js, "Command too long"); |
645 return true; | 646 return true; |
646 } | 647 } |
647 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 648 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 PrintError(js, "Command too long"); | 1308 PrintError(js, "Command too long"); |
1308 return true; | 1309 return true; |
1309 } | 1310 } |
1310 } else { | 1311 } else { |
1311 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); | 1312 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); |
1312 return true; | 1313 return true; |
1313 } | 1314 } |
1314 } | 1315 } |
1315 | 1316 |
1316 | 1317 |
1317 static bool HandleCpu(Isolate* isolate, JSONStream* js) { | |
1318 JSONObject jsobj(js); | |
1319 jsobj.AddProperty("type", "CPU"); | |
1320 jsobj.AddProperty("targetCPU", CPU::Id()); | |
1321 jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware()); | |
1322 return true; | |
1323 } | |
1324 | |
1325 | |
1326 static bool HandleNullCode(uintptr_t pc, JSONStream* js) { | 1318 static bool HandleNullCode(uintptr_t pc, JSONStream* js) { |
1327 // TODO(turnidge): Consider adding/using Object::null_code() for | 1319 // TODO(turnidge): Consider adding/using Object::null_code() for |
1328 // consistent "type". | 1320 // consistent "type". |
1329 Object::null_object().PrintToJSONStream(js, false); | 1321 Object::null_object().PrintToJSONStream(js, false); |
1330 return true; | 1322 return true; |
1331 } | 1323 } |
1332 | 1324 |
1333 | 1325 |
1334 static bool HandleCode(Isolate* isolate, JSONStream* js) { | 1326 static bool HandleCode(Isolate* isolate, JSONStream* js) { |
1335 REQUIRE_COLLECTION_ID("code"); | 1327 REQUIRE_COLLECTION_ID("code"); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 if (js->num_arguments() != 1) { | 1416 if (js->num_arguments() != 1) { |
1425 PrintError(js, "Command too long"); | 1417 PrintError(js, "Command too long"); |
1426 return true; | 1418 return true; |
1427 } | 1419 } |
1428 isolate->class_table()->AllocationProfilePrintToJSONStream(js); | 1420 isolate->class_table()->AllocationProfilePrintToJSONStream(js); |
1429 return true; | 1421 return true; |
1430 } | 1422 } |
1431 | 1423 |
1432 | 1424 |
1433 static bool HandleResume(Isolate* isolate, JSONStream* js) { | 1425 static bool HandleResume(Isolate* isolate, JSONStream* js) { |
1434 // TODO(johnmccutchan): What do I respond with?? | |
1435 if (isolate->message_handler()->pause_on_start()) { | 1426 if (isolate->message_handler()->pause_on_start()) { |
1436 isolate->message_handler()->set_pause_on_start(false); | 1427 isolate->message_handler()->set_pause_on_start(false); |
| 1428 JSONObject jsobj(js); |
| 1429 jsobj.AddProperty("type", "Success"); |
| 1430 jsobj.AddProperty("id", ""); |
1437 return true; | 1431 return true; |
1438 } | 1432 } |
1439 if (isolate->message_handler()->pause_on_exit()) { | 1433 if (isolate->message_handler()->pause_on_exit()) { |
1440 isolate->message_handler()->set_pause_on_exit(false); | 1434 isolate->message_handler()->set_pause_on_exit(false); |
| 1435 JSONObject jsobj(js); |
| 1436 jsobj.AddProperty("type", "Success"); |
| 1437 jsobj.AddProperty("id", ""); |
1441 return true; | 1438 return true; |
1442 } | 1439 } |
| 1440 |
| 1441 PrintError(js, "VM was not paused"); |
1443 return true; | 1442 return true; |
1444 } | 1443 } |
1445 | 1444 |
1446 | 1445 |
1447 static bool HandleHeapMap(Isolate* isolate, JSONStream* js) { | 1446 static bool HandleHeapMap(Isolate* isolate, JSONStream* js) { |
1448 isolate->heap()->PrintHeapMapToJSONStream(js); | 1447 isolate->heap()->PrintHeapMapToJSONStream(js); |
1449 return true; | 1448 return true; |
1450 } | 1449 } |
1451 | 1450 |
1452 | 1451 |
1453 static IsolateMessageHandlerEntry isolate_handlers[] = { | 1452 static IsolateMessageHandlerEntry isolate_handlers[] = { |
1454 { "_echo", HandleIsolateEcho }, | 1453 { "_echo", HandleIsolateEcho }, |
1455 { "", HandleIsolate }, | 1454 { "", HandleIsolate }, |
1456 { "allocationprofile", HandleAllocationProfile }, | 1455 { "allocationprofile", HandleAllocationProfile }, |
1457 { "classes", HandleClasses }, | 1456 { "classes", HandleClasses }, |
1458 { "code", HandleCode }, | 1457 { "code", HandleCode }, |
1459 { "coverage", HandleCoverage }, | 1458 { "coverage", HandleCoverage }, |
1460 { "cpu", HandleCpu }, | |
1461 { "debug", HandleDebug }, | 1459 { "debug", HandleDebug }, |
1462 { "heapmap", HandleHeapMap }, | 1460 { "heapmap", HandleHeapMap }, |
1463 { "libraries", HandleLibraries }, | 1461 { "libraries", HandleLibraries }, |
1464 { "objects", HandleObjects }, | 1462 { "objects", HandleObjects }, |
1465 { "profile", HandleProfile }, | 1463 { "profile", HandleProfile }, |
1466 { "resume", HandleResume }, | 1464 { "resume", HandleResume }, |
1467 { "scripts", HandleScripts }, | 1465 { "scripts", HandleScripts }, |
1468 { "stacktrace", HandleStackTrace }, | 1466 { "stacktrace", HandleStackTrace }, |
1469 }; | 1467 }; |
1470 | 1468 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 | 1550 |
1553 | 1551 |
1554 static bool HandleRootEcho(JSONStream* js) { | 1552 static bool HandleRootEcho(JSONStream* js) { |
1555 JSONObject jsobj(js); | 1553 JSONObject jsobj(js); |
1556 jsobj.AddProperty("type", "message"); | 1554 jsobj.AddProperty("type", "message"); |
1557 PrintArgumentsAndOptions(jsobj, js); | 1555 PrintArgumentsAndOptions(jsobj, js); |
1558 return true; | 1556 return true; |
1559 } | 1557 } |
1560 | 1558 |
1561 | 1559 |
1562 static bool HandleCpu(JSONStream* js) { | 1560 class ServiceIsolateVisitor : public IsolateVisitor { |
| 1561 public: |
| 1562 explicit ServiceIsolateVisitor(JSONArray* jsarr) |
| 1563 : jsarr_(jsarr) { |
| 1564 } |
| 1565 |
| 1566 virtual ~ServiceIsolateVisitor() {} |
| 1567 |
| 1568 void VisitIsolate(Isolate* isolate) { |
| 1569 if (isolate != Dart::vm_isolate() && !Service::IsServiceIsolate(isolate)) { |
| 1570 jsarr_->AddValue(isolate); |
| 1571 } |
| 1572 } |
| 1573 |
| 1574 private: |
| 1575 JSONArray* jsarr_; |
| 1576 }; |
| 1577 |
| 1578 |
| 1579 static bool HandleVM(JSONStream* js) { |
1563 JSONObject jsobj(js); | 1580 JSONObject jsobj(js); |
1564 jsobj.AddProperty("type", "CPU"); | 1581 jsobj.AddProperty("type", "VM"); |
| 1582 jsobj.AddProperty("id", "vm"); |
1565 jsobj.AddProperty("architecture", CPU::Id()); | 1583 jsobj.AddProperty("architecture", CPU::Id()); |
| 1584 jsobj.AddProperty("version", Version::String()); |
| 1585 |
| 1586 int64_t start_time_micros = Dart::vm_isolate()->start_time(); |
| 1587 int64_t uptime_micros = (OS::GetCurrentTimeMicros() - start_time_micros); |
| 1588 double seconds = (static_cast<double>(uptime_micros) / |
| 1589 static_cast<double>(kMicrosecondsPerSecond)); |
| 1590 jsobj.AddProperty("uptime", seconds); |
| 1591 |
| 1592 // Construct the isolate list. |
| 1593 { |
| 1594 JSONArray jsarr(&jsobj, "isolates"); |
| 1595 ServiceIsolateVisitor visitor(&jsarr); |
| 1596 Isolate::VisitIsolates(&visitor); |
| 1597 } |
1566 return true; | 1598 return true; |
1567 } | 1599 } |
1568 | 1600 |
1569 | 1601 |
1570 static RootMessageHandlerEntry root_handlers[] = { | 1602 static RootMessageHandlerEntry root_handlers[] = { |
1571 { "_echo", HandleRootEcho }, | 1603 { "_echo", HandleRootEcho }, |
1572 { "cpu", HandleCpu }, | 1604 { "vm", HandleVM }, |
1573 }; | 1605 }; |
1574 | 1606 |
1575 | 1607 |
1576 static RootMessageHandler FindRootMessageHandler(const char* command) { | 1608 static RootMessageHandler FindRootMessageHandler(const char* command) { |
1577 intptr_t num_message_handlers = sizeof(root_handlers) / | 1609 intptr_t num_message_handlers = sizeof(root_handlers) / |
1578 sizeof(root_handlers[0]); | 1610 sizeof(root_handlers[0]); |
1579 for (intptr_t i = 0; i < num_message_handlers; i++) { | 1611 for (intptr_t i = 0; i < num_message_handlers; i++) { |
1580 const RootMessageHandlerEntry& entry = root_handlers[i]; | 1612 const RootMessageHandlerEntry& entry = root_handlers[i]; |
1581 if (strcmp(command, entry.command) == 0) { | 1613 if (strcmp(command, entry.command) == 0) { |
1582 return entry.handler; | 1614 return entry.handler; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1678 while (current != NULL) { | 1710 while (current != NULL) { |
1679 if (strcmp(name, current->name()) == 0) { | 1711 if (strcmp(name, current->name()) == 0) { |
1680 return current; | 1712 return current; |
1681 } | 1713 } |
1682 current = current->next(); | 1714 current = current->next(); |
1683 } | 1715 } |
1684 return NULL; | 1716 return NULL; |
1685 } | 1717 } |
1686 | 1718 |
1687 } // namespace dart | 1719 } // namespace dart |
OLD | NEW |