Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: runtime/vm/service.cc

Issue 1143783003: Add the streamListen and streamCancel rpcs to the vm service. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: before commit Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/service.h ('k') | runtime/vm/service/client.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "platform/globals.h" 8 #include "platform/globals.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 return zone->PrintToString("objects/%" Pd "", id); 67 return zone->PrintToString("objects/%" Pd "", id);
68 } 68 }
69 69
70 70
71 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs. 71 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs.
72 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; 72 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
73 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; 73 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
74 struct ServiceMethodDescriptor; 74 struct ServiceMethodDescriptor;
75 ServiceMethodDescriptor* FindMethod(const char* method_name); 75 ServiceMethodDescriptor* FindMethod(const char* method_name);
76 76
77 // TODO(turnidge): Build a general framework later. For now, we have
78 // a small set of well-known streams.
79 bool Service::needs_isolate_events_ = false;
80 bool Service::needs_debug_events_ = false;
81 bool Service::needs_gc_events_ = false;
82 bool Service::needs_echo_events_ = false;
83 bool Service::needs_graph_events_ = false;
84
85 void Service::ListenStream(const char* stream_id) {
86 if (FLAG_trace_service) {
87 OS::Print("vm-service: starting stream '%s'\n",
88 stream_id);
89 }
90 if (strcmp(stream_id, "Isolate") == 0) {
91 needs_isolate_events_ = true;
92 } else if (strcmp(stream_id, "Debug") == 0) {
93 needs_debug_events_ = true;
94 } else if (strcmp(stream_id, "GC") == 0) {
95 needs_gc_events_ = true;
96 } else if (strcmp(stream_id, "_Echo") == 0) {
97 needs_echo_events_ = true;
98 } else if (strcmp(stream_id, "_Graph") == 0) {
99 needs_graph_events_ = true;
100 } else {
101 UNREACHABLE();
102 }
103 }
104
105 void Service::CancelStream(const char* stream_id) {
106 if (FLAG_trace_service) {
107 OS::Print("vm-service: stopping stream '%s'\n",
108 stream_id);
109 }
110 if (strcmp(stream_id, "Isolate") == 0) {
111 needs_isolate_events_ = false;
112 } else if (strcmp(stream_id, "Debug") == 0) {
113 needs_debug_events_ = false;
114 } else if (strcmp(stream_id, "GC") == 0) {
115 needs_gc_events_ = false;
116 } else if (strcmp(stream_id, "_Echo") == 0) {
117 needs_echo_events_ = false;
118 } else if (strcmp(stream_id, "_Graph") == 0) {
119 needs_graph_events_ = false;
120 } else {
121 UNREACHABLE();
122 }
123 }
124
77 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 125 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
78 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 126 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
79 return reinterpret_cast<uint8_t*>(new_ptr); 127 return reinterpret_cast<uint8_t*>(new_ptr);
80 } 128 }
81 129
82 static void PrintMissingParamError(JSONStream* js, 130 static void PrintMissingParamError(JSONStream* js,
83 const char* param) { 131 const char* param) {
84 js->PrintError(kInvalidParams, 132 js->PrintError(kInvalidParams,
85 "%s expects the '%s' parameter", js->method(), param); 133 "%s expects the '%s' parameter", js->method(), param);
86 } 134 }
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 InvokeMethod(isolate, msg_instance); 533 InvokeMethod(isolate, msg_instance);
486 } 534 }
487 535
488 536
489 void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { 537 void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
490 ASSERT(isolate != NULL); 538 ASSERT(isolate != NULL);
491 InvokeMethod(isolate, msg); 539 InvokeMethod(isolate, msg);
492 } 540 }
493 541
494 542
495 bool Service::NeedsEvents() { 543 void Service::SendEvent(const char* stream_id,
496 return ServiceIsolate::IsRunning(); 544 const char* event_type,
497 } 545 const Object& event_message) {
498
499
500 void Service::SendEvent(intptr_t eventType,
501 const Object& eventMessage) {
502 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(Isolate::Current())); 546 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(Isolate::Current()));
503 if (!ServiceIsolate::IsRunning()) { 547 if (!ServiceIsolate::IsRunning()) {
504 return; 548 return;
505 } 549 }
506 Isolate* isolate = Isolate::Current(); 550 Isolate* isolate = Isolate::Current();
507 ASSERT(isolate != NULL); 551 ASSERT(isolate != NULL);
508 HANDLESCOPE(isolate); 552 HANDLESCOPE(isolate);
509 553
554 const Array& list = Array::Handle(Array::New(2));
555 ASSERT(!list.IsNull());
556 const String& stream_id_str = String::Handle(String::New(stream_id));
557 list.SetAt(0, stream_id_str);
558 list.SetAt(1, event_message);
559
510 // Push the event to port_. 560 // Push the event to port_.
511 uint8_t* data = NULL; 561 uint8_t* data = NULL;
512 MessageWriter writer(&data, &allocator, false); 562 MessageWriter writer(&data, &allocator, false);
513 writer.WriteMessage(eventMessage); 563 writer.WriteMessage(list);
514 intptr_t len = writer.BytesWritten(); 564 intptr_t len = writer.BytesWritten();
515 if (FLAG_trace_service) { 565 if (FLAG_trace_service) {
516 OS::Print("vm-service: Pushing event of type %" Pd ", len %" Pd "\n", 566 OS::Print(
517 eventType, len); 567 "vm-service: Pushing event of type %s to stream %s, len %" Pd "\n",
568 event_type, stream_id, len);
518 } 569 }
519 // TODO(turnidge): For now we ignore failure to send an event. Revisit? 570 // TODO(turnidge): For now we ignore failure to send an event. Revisit?
520 PortMap::PostMessage( 571 PortMap::PostMessage(
521 new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority)); 572 new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority));
522 } 573 }
523 574
524 575
525 void Service::SendEvent(const String& meta, 576 void Service::SendEventWithData(const char* stream_id,
526 const uint8_t* data, 577 const char* event_type,
527 intptr_t size) { 578 const String& meta,
579 const uint8_t* data,
580 intptr_t size) {
528 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] 581 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data]
529 const intptr_t meta_bytes = Utf8::Length(meta); 582 const intptr_t meta_bytes = Utf8::Length(meta);
530 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; 583 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size;
531 const TypedData& message = TypedData::Handle( 584 const TypedData& message = TypedData::Handle(
532 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); 585 TypedData::New(kTypedDataUint8ArrayCid, total_bytes));
533 intptr_t offset = 0; 586 intptr_t offset = 0;
534 // TODO(koda): Rename these methods SetHostUint64, etc. 587 // TODO(koda): Rename these methods SetHostUint64, etc.
535 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); 588 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes));
536 offset += sizeof(uint64_t); 589 offset += sizeof(uint64_t);
537 { 590 {
538 NoSafepointScope no_safepoint; 591 NoSafepointScope no_safepoint;
539 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); 592 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes);
540 offset += meta_bytes; 593 offset += meta_bytes;
541 } 594 }
542 // TODO(koda): It would be nice to avoid this copy (requires changes to 595 // TODO(koda): It would be nice to avoid this copy (requires changes to
543 // MessageWriter code). 596 // MessageWriter code).
544 { 597 {
545 NoSafepointScope no_safepoint; 598 NoSafepointScope no_safepoint;
546 memmove(message.DataAddr(offset), data, size); 599 memmove(message.DataAddr(offset), data, size);
547 offset += size; 600 offset += size;
548 } 601 }
549 ASSERT(offset == total_bytes); 602 ASSERT(offset == total_bytes);
550 // TODO(turnidge): Pass the real eventType here. 603 SendEvent(stream_id, event_type, message);
551 SendEvent(0, message);
552 } 604 }
553 605
554 606
555 void Service::HandleEvent(ServiceEvent* event) { 607 void Service::HandleEvent(ServiceEvent* event) {
556 if (ServiceIsolate::IsServiceIsolateDescendant(event->isolate())) { 608 if (ServiceIsolate::IsServiceIsolateDescendant(event->isolate())) {
557 return; 609 return;
558 } 610 }
559 JSONStream js; 611 JSONStream js;
612 const char* stream_id = event->stream_id();
613 ASSERT(stream_id != NULL);
560 { 614 {
561 JSONObject jsobj(&js); 615 JSONObject jsobj(&js);
562 jsobj.AddProperty("event", event); 616 jsobj.AddProperty("event", event);
617 jsobj.AddProperty("streamId", stream_id);
563 } 618 }
564 const String& message = String::Handle(String::New(js.ToCString())); 619 const String& message = String::Handle(String::New(js.ToCString()));
565 SendEvent(event->type(), message); 620 SendEvent(stream_id, ServiceEvent::EventTypeToCString(event->type()),
621 message);
566 } 622 }
567 623
568 624
569 class EmbedderServiceHandler { 625 class EmbedderServiceHandler {
570 public: 626 public:
571 explicit EmbedderServiceHandler(const char* name) : name_(NULL), 627 explicit EmbedderServiceHandler(const char* name) : name_(NULL),
572 callback_(NULL), 628 callback_(NULL),
573 user_data_(NULL), 629 user_data_(NULL),
574 next_(NULL) { 630 next_(NULL) {
575 ASSERT(name != NULL); 631 ASSERT(name != NULL);
(...skipping 28 matching lines...) Expand all
604 EmbedderServiceHandler* next_; 660 EmbedderServiceHandler* next_;
605 }; 661 };
606 662
607 663
608 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler, 664 void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler,
609 JSONStream* js) { 665 JSONStream* js) {
610 ASSERT(handler != NULL); 666 ASSERT(handler != NULL);
611 Dart_ServiceRequestCallback callback = handler->callback(); 667 Dart_ServiceRequestCallback callback = handler->callback();
612 ASSERT(callback != NULL); 668 ASSERT(callback != NULL);
613 const char* r = NULL; 669 const char* r = NULL;
614 const char* name = js->method(); 670 const char* method = js->method();
615 const char** keys = js->param_keys(); 671 const char** keys = js->param_keys();
616 const char** values = js->param_values(); 672 const char** values = js->param_values();
617 r = callback(name, keys, values, js->num_params(), handler->user_data()); 673 r = callback(method, keys, values, js->num_params(), handler->user_data());
618 ASSERT(r != NULL); 674 ASSERT(r != NULL);
619 // TODO(johnmccutchan): Allow for NULL returns? 675 // TODO(johnmccutchan): Allow for NULL returns?
620 TextBuffer* buffer = js->buffer(); 676 TextBuffer* buffer = js->buffer();
621 buffer->AddString(r); 677 buffer->AddString(r);
622 free(const_cast<char*>(r)); 678 free(const_cast<char*>(r));
623 } 679 }
624 680
625 681
626 void Service::RegisterIsolateEmbedderCallback( 682 void Service::RegisterIsolateEmbedderCallback(
627 const char* name, 683 const char* name,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 JSONObject jsobj(&js); 820 JSONObject jsobj(&js);
765 { 821 {
766 JSONObject event(&jsobj, "event"); 822 JSONObject event(&jsobj, "event");
767 event.AddProperty("type", "ServiceEvent"); 823 event.AddProperty("type", "ServiceEvent");
768 event.AddProperty("eventType", "_Echo"); 824 event.AddProperty("eventType", "_Echo");
769 event.AddProperty("isolate", isolate); 825 event.AddProperty("isolate", isolate);
770 if (text != NULL) { 826 if (text != NULL) {
771 event.AddProperty("text", text); 827 event.AddProperty("text", text);
772 } 828 }
773 } 829 }
830 jsobj.AddProperty("streamId", "_Echo");
774 } 831 }
775 const String& message = String::Handle(String::New(js.ToCString())); 832 const String& message = String::Handle(String::New(js.ToCString()));
776 uint8_t data[] = {0, 128, 255}; 833 uint8_t data[] = {0, 128, 255};
777 SendEvent(message, data, sizeof(data)); 834 SendEventWithData("_Echo", "_Echo", message, data, sizeof(data));
778 } 835 }
779 836
780 837
781 static bool TriggerEchoEvent(Isolate* isolate, JSONStream* js) { 838 static bool TriggerEchoEvent(Isolate* isolate, JSONStream* js) {
782 Service::SendEchoEvent(isolate, js->LookupParam("text")); 839 Service::SendEchoEvent(isolate, js->LookupParam("text"));
783 JSONObject jsobj(js); 840 JSONObject jsobj(js);
784 return HandleCommonEcho(&jsobj, js); 841 return HandleCommonEcho(&jsobj, js);
785 } 842 }
786 843
787 844
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 NULL, 2116 NULL,
2060 }; 2117 };
2061 2118
2062 2119
2063 static bool Resume(Isolate* isolate, JSONStream* js) { 2120 static bool Resume(Isolate* isolate, JSONStream* js) {
2064 const char* step_param = js->LookupParam("step"); 2121 const char* step_param = js->LookupParam("step");
2065 if (isolate->message_handler()->paused_on_start()) { 2122 if (isolate->message_handler()->paused_on_start()) {
2066 isolate->message_handler()->set_pause_on_start(false); 2123 isolate->message_handler()->set_pause_on_start(false);
2067 JSONObject jsobj(js); 2124 JSONObject jsobj(js);
2068 jsobj.AddProperty("type", "Success"); 2125 jsobj.AddProperty("type", "Success");
2069 { 2126 if (Service::NeedsDebugEvents()) {
2070 ServiceEvent event(isolate, ServiceEvent::kResume); 2127 ServiceEvent event(isolate, ServiceEvent::kResume);
2071 Service::HandleEvent(&event); 2128 Service::HandleEvent(&event);
2072 } 2129 }
2073 return true; 2130 return true;
2074 } 2131 }
2075 if (isolate->message_handler()->paused_on_exit()) { 2132 if (isolate->message_handler()->paused_on_exit()) {
2076 isolate->message_handler()->set_pause_on_exit(false); 2133 isolate->message_handler()->set_pause_on_exit(false);
2077 JSONObject jsobj(js); 2134 JSONObject jsobj(js);
2078 jsobj.AddProperty("type", "Success"); 2135 jsobj.AddProperty("type", "Success");
2079 // We don't send a resume event because we will be exiting. 2136 // We don't send a resume event because we will be exiting.
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 graph.Serialize(&stream); 2312 graph.Serialize(&stream);
2256 JSONStream js; 2313 JSONStream js;
2257 { 2314 {
2258 JSONObject jsobj(&js); 2315 JSONObject jsobj(&js);
2259 { 2316 {
2260 JSONObject event(&jsobj, "event"); 2317 JSONObject event(&jsobj, "event");
2261 event.AddProperty("type", "ServiceEvent"); 2318 event.AddProperty("type", "ServiceEvent");
2262 event.AddProperty("eventType", "_Graph"); 2319 event.AddProperty("eventType", "_Graph");
2263 event.AddProperty("isolate", isolate); 2320 event.AddProperty("isolate", isolate);
2264 } 2321 }
2322 jsobj.AddProperty("streamId", "_Graph");
2265 } 2323 }
2266 const String& message = String::Handle(String::New(js.ToCString())); 2324 const String& message = String::Handle(String::New(js.ToCString()));
2267 SendEvent(message, buffer, stream.bytes_written()); 2325 SendEventWithData("_Graph", "_Graph", message,
2326 buffer, stream.bytes_written());
2268 } 2327 }
2269 2328
2270 2329
2271 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { 2330 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) {
2331 if (!Service::NeedsDebugEvents()) {
2332 return;
2333 }
2272 ServiceEvent event(isolate, ServiceEvent::kInspect); 2334 ServiceEvent event(isolate, ServiceEvent::kInspect);
2273 event.set_inspectee(&inspectee); 2335 event.set_inspectee(&inspectee);
2274 Service::HandleEvent(&event); 2336 Service::HandleEvent(&event);
2275 } 2337 }
2276 2338
2277 2339
2278 class ContainsAddressVisitor : public FindObjectVisitor { 2340 class ContainsAddressVisitor : public FindObjectVisitor {
2279 public: 2341 public:
2280 ContainsAddressVisitor(Isolate* isolate, uword addr) 2342 ContainsAddressVisitor(Isolate* isolate, uword addr)
2281 : FindObjectVisitor(isolate), addr_(addr) { } 2343 : FindObjectVisitor(isolate), addr_(addr) { }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2543 2605
2544 static const MethodParameter* set_name_params[] = { 2606 static const MethodParameter* set_name_params[] = {
2545 ISOLATE_PARAMETER, 2607 ISOLATE_PARAMETER,
2546 new MethodParameter("name", true), 2608 new MethodParameter("name", true),
2547 NULL, 2609 NULL,
2548 }; 2610 };
2549 2611
2550 2612
2551 static bool SetName(Isolate* isolate, JSONStream* js) { 2613 static bool SetName(Isolate* isolate, JSONStream* js) {
2552 isolate->set_debugger_name(js->LookupParam("name")); 2614 isolate->set_debugger_name(js->LookupParam("name"));
2553 { 2615 if (Service::NeedsIsolateEvents()) {
2554 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); 2616 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
2555 Service::HandleEvent(&event); 2617 Service::HandleEvent(&event);
2556 } 2618 }
2557 JSONObject jsobj(js); 2619 JSONObject jsobj(js);
2558 jsobj.AddProperty("type", "Success"); 2620 jsobj.AddProperty("type", "Success");
2559 return true; 2621 return true;
2560 } 2622 }
2561 2623
2562 2624
2563 static ServiceMethodDescriptor service_methods_[] = { 2625 static ServiceMethodDescriptor service_methods_[] = {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 ServiceMethodDescriptor& method = service_methods_[i]; 2708 ServiceMethodDescriptor& method = service_methods_[i];
2647 if (strcmp(method_name, method.name) == 0) { 2709 if (strcmp(method_name, method.name) == 0) {
2648 return &method; 2710 return &method;
2649 } 2711 }
2650 } 2712 }
2651 return NULL; 2713 return NULL;
2652 } 2714 }
2653 2715
2654 2716
2655 } // namespace dart 2717 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/service.h ('k') | runtime/vm/service/client.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698