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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 PrintError(js, "Command too long"); | 1345 PrintError(js, "Command too long"); |
1345 return true; | 1346 return true; |
1346 } | 1347 } |
1347 } else { | 1348 } else { |
1348 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); | 1349 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); |
1349 return true; | 1350 return true; |
1350 } | 1351 } |
1351 } | 1352 } |
1352 | 1353 |
1353 | 1354 |
1354 static bool HandleCpu(Isolate* isolate, JSONStream* js) { | |
1355 JSONObject jsobj(js); | |
1356 jsobj.AddProperty("type", "CPU"); | |
1357 jsobj.AddProperty("targetCPU", CPU::Id()); | |
1358 jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware()); | |
1359 return true; | |
1360 } | |
1361 | |
1362 | |
1363 static bool HandleNullCode(uintptr_t pc, JSONStream* js) { | 1355 static bool HandleNullCode(uintptr_t pc, JSONStream* js) { |
1364 // TODO(turnidge): Consider adding/using Object::null_code() for | 1356 // TODO(turnidge): Consider adding/using Object::null_code() for |
1365 // consistent "type". | 1357 // consistent "type". |
1366 Object::null_object().PrintToJSONStream(js, false); | 1358 Object::null_object().PrintToJSONStream(js, false); |
1367 return true; | 1359 return true; |
1368 } | 1360 } |
1369 | 1361 |
1370 | 1362 |
1371 static bool HandleCode(Isolate* isolate, JSONStream* js) { | 1363 static bool HandleCode(Isolate* isolate, JSONStream* js) { |
1372 REQUIRE_COLLECTION_ID("code"); | 1364 REQUIRE_COLLECTION_ID("code"); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 if (js->num_arguments() != 1) { | 1453 if (js->num_arguments() != 1) { |
1462 PrintError(js, "Command too long"); | 1454 PrintError(js, "Command too long"); |
1463 return true; | 1455 return true; |
1464 } | 1456 } |
1465 isolate->class_table()->AllocationProfilePrintToJSONStream(js); | 1457 isolate->class_table()->AllocationProfilePrintToJSONStream(js); |
1466 return true; | 1458 return true; |
1467 } | 1459 } |
1468 | 1460 |
1469 | 1461 |
1470 static bool HandleResume(Isolate* isolate, JSONStream* js) { | 1462 static bool HandleResume(Isolate* isolate, JSONStream* js) { |
1471 // TODO(johnmccutchan): What do I respond with?? | |
1472 if (isolate->message_handler()->pause_on_start()) { | 1463 if (isolate->message_handler()->pause_on_start()) { |
1473 isolate->message_handler()->set_pause_on_start(false); | 1464 isolate->message_handler()->set_pause_on_start(false); |
| 1465 JSONObject jsobj(js); |
| 1466 jsobj.AddProperty("type", "Success"); |
| 1467 jsobj.AddProperty("id", ""); |
1474 return true; | 1468 return true; |
1475 } | 1469 } |
1476 if (isolate->message_handler()->pause_on_exit()) { | 1470 if (isolate->message_handler()->pause_on_exit()) { |
1477 isolate->message_handler()->set_pause_on_exit(false); | 1471 isolate->message_handler()->set_pause_on_exit(false); |
| 1472 JSONObject jsobj(js); |
| 1473 jsobj.AddProperty("type", "Success"); |
| 1474 jsobj.AddProperty("id", ""); |
1478 return true; | 1475 return true; |
1479 } | 1476 } |
| 1477 |
| 1478 PrintError(js, "VM was not paused"); |
1480 return true; | 1479 return true; |
1481 } | 1480 } |
1482 | 1481 |
1483 | 1482 |
1484 static bool HandleTypeArguments(Isolate* isolate, JSONStream* js) { | 1483 static bool HandleTypeArguments(Isolate* isolate, JSONStream* js) { |
1485 ObjectStore* object_store = isolate->object_store(); | 1484 ObjectStore* object_store = isolate->object_store(); |
1486 const Array& table = Array::Handle(object_store->canonical_type_arguments()); | 1485 const Array& table = Array::Handle(object_store->canonical_type_arguments()); |
1487 ASSERT(table.Length() > 0); | 1486 ASSERT(table.Length() > 0); |
1488 TypeArguments& type_args = TypeArguments::Handle(); | 1487 TypeArguments& type_args = TypeArguments::Handle(); |
1489 const intptr_t table_size = table.Length() - 1; | 1488 const intptr_t table_size = table.Length() - 1; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 } | 1538 } |
1540 | 1539 |
1541 | 1540 |
1542 static IsolateMessageHandlerEntry isolate_handlers[] = { | 1541 static IsolateMessageHandlerEntry isolate_handlers[] = { |
1543 { "_echo", HandleIsolateEcho }, | 1542 { "_echo", HandleIsolateEcho }, |
1544 { "", HandleIsolate }, | 1543 { "", HandleIsolate }, |
1545 { "allocationprofile", HandleAllocationProfile }, | 1544 { "allocationprofile", HandleAllocationProfile }, |
1546 { "classes", HandleClasses }, | 1545 { "classes", HandleClasses }, |
1547 { "code", HandleCode }, | 1546 { "code", HandleCode }, |
1548 { "coverage", HandleCoverage }, | 1547 { "coverage", HandleCoverage }, |
1549 { "cpu", HandleCpu }, | |
1550 { "debug", HandleDebug }, | 1548 { "debug", HandleDebug }, |
1551 { "heapmap", HandleHeapMap }, | 1549 { "heapmap", HandleHeapMap }, |
1552 { "libraries", HandleLibraries }, | 1550 { "libraries", HandleLibraries }, |
1553 { "objects", HandleObjects }, | 1551 { "objects", HandleObjects }, |
1554 { "profile", HandleProfile }, | 1552 { "profile", HandleProfile }, |
1555 { "resume", HandleResume }, | 1553 { "resume", HandleResume }, |
1556 { "scripts", HandleScripts }, | 1554 { "scripts", HandleScripts }, |
1557 { "stacktrace", HandleStackTrace }, | 1555 { "stacktrace", HandleStackTrace }, |
1558 { "typearguments", HandleTypeArguments }, | 1556 { "typearguments", HandleTypeArguments }, |
1559 }; | 1557 }; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 | 1640 |
1643 | 1641 |
1644 static bool HandleRootEcho(JSONStream* js) { | 1642 static bool HandleRootEcho(JSONStream* js) { |
1645 JSONObject jsobj(js); | 1643 JSONObject jsobj(js); |
1646 jsobj.AddProperty("type", "message"); | 1644 jsobj.AddProperty("type", "message"); |
1647 PrintArgumentsAndOptions(jsobj, js); | 1645 PrintArgumentsAndOptions(jsobj, js); |
1648 return true; | 1646 return true; |
1649 } | 1647 } |
1650 | 1648 |
1651 | 1649 |
1652 static bool HandleCpu(JSONStream* js) { | 1650 class ServiceIsolateVisitor : public IsolateVisitor { |
| 1651 public: |
| 1652 explicit ServiceIsolateVisitor(JSONArray* jsarr) |
| 1653 : jsarr_(jsarr) { |
| 1654 } |
| 1655 |
| 1656 virtual ~ServiceIsolateVisitor() {} |
| 1657 |
| 1658 void VisitIsolate(Isolate* isolate) { |
| 1659 if (isolate != Dart::vm_isolate() && !Service::IsServiceIsolate(isolate)) { |
| 1660 jsarr_->AddValue(isolate); |
| 1661 } |
| 1662 } |
| 1663 |
| 1664 private: |
| 1665 JSONArray* jsarr_; |
| 1666 }; |
| 1667 |
| 1668 |
| 1669 static bool HandleVM(JSONStream* js) { |
1653 JSONObject jsobj(js); | 1670 JSONObject jsobj(js); |
1654 jsobj.AddProperty("type", "CPU"); | 1671 jsobj.AddProperty("type", "VM"); |
| 1672 jsobj.AddProperty("id", "vm"); |
1655 jsobj.AddProperty("architecture", CPU::Id()); | 1673 jsobj.AddProperty("architecture", CPU::Id()); |
| 1674 jsobj.AddProperty("version", Version::String()); |
| 1675 |
| 1676 int64_t start_time_micros = Dart::vm_isolate()->start_time(); |
| 1677 int64_t uptime_micros = (OS::GetCurrentTimeMicros() - start_time_micros); |
| 1678 double seconds = (static_cast<double>(uptime_micros) / |
| 1679 static_cast<double>(kMicrosecondsPerSecond)); |
| 1680 jsobj.AddProperty("uptime", seconds); |
| 1681 |
| 1682 // Construct the isolate list. |
| 1683 { |
| 1684 JSONArray jsarr(&jsobj, "isolates"); |
| 1685 ServiceIsolateVisitor visitor(&jsarr); |
| 1686 Isolate::VisitIsolates(&visitor); |
| 1687 } |
1656 return true; | 1688 return true; |
1657 } | 1689 } |
1658 | 1690 |
1659 | 1691 |
1660 static RootMessageHandlerEntry root_handlers[] = { | 1692 static RootMessageHandlerEntry root_handlers[] = { |
1661 { "_echo", HandleRootEcho }, | 1693 { "_echo", HandleRootEcho }, |
1662 { "cpu", HandleCpu }, | 1694 { "vm", HandleVM }, |
1663 }; | 1695 }; |
1664 | 1696 |
1665 | 1697 |
1666 static RootMessageHandler FindRootMessageHandler(const char* command) { | 1698 static RootMessageHandler FindRootMessageHandler(const char* command) { |
1667 intptr_t num_message_handlers = sizeof(root_handlers) / | 1699 intptr_t num_message_handlers = sizeof(root_handlers) / |
1668 sizeof(root_handlers[0]); | 1700 sizeof(root_handlers[0]); |
1669 for (intptr_t i = 0; i < num_message_handlers; i++) { | 1701 for (intptr_t i = 0; i < num_message_handlers; i++) { |
1670 const RootMessageHandlerEntry& entry = root_handlers[i]; | 1702 const RootMessageHandlerEntry& entry = root_handlers[i]; |
1671 if (strcmp(command, entry.command) == 0) { | 1703 if (strcmp(command, entry.command) == 0) { |
1672 return entry.handler; | 1704 return entry.handler; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 while (current != NULL) { | 1800 while (current != NULL) { |
1769 if (strcmp(name, current->name()) == 0) { | 1801 if (strcmp(name, current->name()) == 0) { |
1770 return current; | 1802 return current; |
1771 } | 1803 } |
1772 current = current->next(); | 1804 current = current->next(); |
1773 } | 1805 } |
1774 return NULL; | 1806 return NULL; |
1775 } | 1807 } |
1776 | 1808 |
1777 } // namespace dart | 1809 } // namespace dart |
OLD | NEW |