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

Unified Diff: runtime/vm/service.cc

Issue 1232193003: Provide stdout and stderr output in the Observatory debugger. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: tidy up Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/service.cc
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 4cbc5ddba46f142d49aa4c71cb4551b87d1c3ebb..0590c1589f84d62858bda9f3b93d029612ebad69 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -5,6 +5,7 @@
#include "vm/service.h"
#include "include/dart_api.h"
+#include "include/dart_native_api.h"
#include "platform/globals.h"
#include "vm/compiler.h"
@@ -74,32 +75,50 @@ EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
struct ServiceMethodDescriptor;
ServiceMethodDescriptor* FindMethod(const char* method_name);
-// TODO(turnidge): Build a general framework later. For now, we have
-// a small set of well-known streams.
+
+// These are the set of streams known to the core VM.
+const char* const Service::kIsolateStreamId = "Isolate";
+const char* const Service::kDebugStreamId = "Debug";
+const char* const Service::kGCStreamId = "GC";
+const char* const Service::kEchoStreamId = "_Echo";
+const char* const Service::kGraphStreamId = "_Graph";
Cutch 2015/07/13 14:10:29 Would be nice if we had an array of streams (with
turnidge 2015/07/13 22:50:36 Done.
+
+
bool Service::needs_isolate_events_ = false;
bool Service::needs_debug_events_ = false;
bool Service::needs_gc_events_ = false;
bool Service::needs_echo_events_ = false;
bool Service::needs_graph_events_ = false;
-void Service::ListenStream(const char* stream_id) {
+// Support for streams defined in embedders.
+Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL;
+Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL;
+
+
+bool Service::ListenStream(const char* stream_id) {
if (FLAG_trace_service) {
OS::Print("vm-service: starting stream '%s'\n",
stream_id);
}
- if (strcmp(stream_id, "Isolate") == 0) {
+ if (strcmp(stream_id, kIsolateStreamId) == 0) {
needs_isolate_events_ = true;
- } else if (strcmp(stream_id, "Debug") == 0) {
+ return true;
+ } else if (strcmp(stream_id, kDebugStreamId) == 0) {
needs_debug_events_ = true;
- } else if (strcmp(stream_id, "GC") == 0) {
+ return true;
+ } else if (strcmp(stream_id, kGCStreamId) == 0) {
needs_gc_events_ = true;
- } else if (strcmp(stream_id, "_Echo") == 0) {
+ return true;
+ } else if (strcmp(stream_id, kEchoStreamId) == 0) {
needs_echo_events_ = true;
- } else if (strcmp(stream_id, "_Graph") == 0) {
+ return true;
+ } else if (strcmp(stream_id, kGraphStreamId) == 0) {
needs_graph_events_ = true;
- } else {
- UNREACHABLE();
+ return true;
+ } else if (stream_listen_callback_) {
+ return (*stream_listen_callback_)(stream_id);
}
+ return false;
}
void Service::CancelStream(const char* stream_id) {
@@ -107,18 +126,18 @@ void Service::CancelStream(const char* stream_id) {
OS::Print("vm-service: stopping stream '%s'\n",
stream_id);
}
- if (strcmp(stream_id, "Isolate") == 0) {
+ if (strcmp(stream_id, kIsolateStreamId) == 0) {
needs_isolate_events_ = false;
- } else if (strcmp(stream_id, "Debug") == 0) {
+ } else if (strcmp(stream_id, kDebugStreamId) == 0) {
needs_debug_events_ = false;
- } else if (strcmp(stream_id, "GC") == 0) {
+ } else if (strcmp(stream_id, kGCStreamId) == 0) {
needs_gc_events_ = false;
- } else if (strcmp(stream_id, "_Echo") == 0) {
+ } else if (strcmp(stream_id, kEchoStreamId) == 0) {
needs_echo_events_ = false;
- } else if (strcmp(stream_id, "_Graph") == 0) {
+ } else if (strcmp(stream_id, kGraphStreamId) == 0) {
needs_graph_events_ = false;
- } else {
- UNREACHABLE();
+ } else if (stream_cancel_callback_) {
+ return (*stream_cancel_callback_)(stream_id);
}
}
@@ -578,6 +597,7 @@ void Service::SendEvent(const char* stream_id,
}
+// TODO(turnidge): Rewrite this method to use Post_CObject instead.
void Service::SendEventWithData(const char* stream_id,
const char* event_type,
const String& meta,
@@ -613,6 +633,9 @@ void Service::HandleEvent(ServiceEvent* event) {
if (ServiceIsolate::IsServiceIsolateDescendant(event->isolate())) {
return;
}
+ if (!ServiceIsolate::IsRunning()) {
+ return;
+ }
JSONStream js;
const char* stream_id = event->stream_id();
ASSERT(stream_id != NULL);
@@ -621,9 +644,35 @@ void Service::HandleEvent(ServiceEvent* event) {
jsobj.AddProperty("event", event);
jsobj.AddProperty("streamId", stream_id);
}
- const String& message = String::Handle(String::New(js.ToCString()));
- SendEvent(stream_id, ServiceEvent::EventTypeToCString(event->type()),
- message);
+
+ // Message is of the format [<stream id>, <json string>].
+ //
+ // Build the event message in the C heap to avoid dart heap
+ // allocation. This method can be called while we have acquired a
+ // direct pointer to typed data, so we can't allocate here.
+ Dart_CObject list_cobj;
+ Dart_CObject* list_values[2];
+ list_cobj.type = Dart_CObject_kArray;
+ list_cobj.value.as_array.length = 2;
+ list_cobj.value.as_array.values = list_values;
+
+ Dart_CObject stream_id_cobj;
+ stream_id_cobj.type = Dart_CObject_kString;
+ stream_id_cobj.value.as_string = const_cast<char*>(stream_id);
+ list_values[0] = &stream_id_cobj;
+
+ Dart_CObject json_cobj;
+ json_cobj.type = Dart_CObject_kString;
+ json_cobj.value.as_string = const_cast<char*>(js.ToCString());
+ list_values[1] = &json_cobj;
+
+ if (FLAG_trace_service) {
+ OS::Print(
+ "vm-service: Pushing event of type %s to stream %s\n",
+ event->KindAsCString(), stream_id);
+ }
+
+ Dart_PostCObject(ServiceIsolate::Port(), &list_cobj);
}
@@ -747,6 +796,14 @@ void Service::RegisterRootEmbedderCallback(
}
+void Service::SetEmbedderStreamCallbacks(
+ Dart_ServiceStreamListenCallback listen_callback,
+ Dart_ServiceStreamCancelCallback cancel_callback) {
+ stream_listen_callback_ = listen_callback;
+ stream_cancel_callback_ = cancel_callback;
+}
+
+
EmbedderServiceHandler* Service::FindRootEmbedderHandler(
const char* name) {
EmbedderServiceHandler* current = root_service_handler_head_;
@@ -830,11 +887,11 @@ void Service::SendEchoEvent(Isolate* isolate, const char* text) {
event.AddProperty("text", text);
}
}
- jsobj.AddProperty("streamId", "_Echo");
+ jsobj.AddProperty("streamId", kEchoStreamId);
}
const String& message = String::Handle(String::New(js.ToCString()));
uint8_t data[] = {0, 128, 255};
- SendEventWithData("_Echo", "_Echo", message, data, sizeof(data));
+ SendEventWithData(kEchoStreamId, "_Echo", message, data, sizeof(data));
}
@@ -2349,7 +2406,7 @@ void Service::SendGraphEvent(Isolate* isolate) {
event.AddProperty("chunkCount", num_chunks);
event.AddProperty("nodeCount", node_count);
}
- jsobj.AddProperty("streamId", "_Graph");
+ jsobj.AddProperty("streamId", kGraphStreamId);
}
const String& message = String::Handle(String::New(js.ToCString()));
@@ -2359,7 +2416,8 @@ void Service::SendGraphEvent(Isolate* isolate) {
? stream.bytes_written() - (i * kChunkSize)
: kChunkSize;
- SendEventWithData("_Graph", "_Graph", message, chunk_start, chunk_size);
+ SendEventWithData(kGraphStreamId, "_Graph", message,
+ chunk_start, chunk_size);
}
}
@@ -2374,6 +2432,22 @@ void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) {
}
+void Service::SendEmbedderEvent(Isolate* isolate,
+ const char* stream_id,
+ const char* event_kind,
+ const uint8_t* bytes,
+ intptr_t bytes_len) {
+ if (!Service::NeedsDebugEvents()) {
+ return;
+ }
+ ServiceEvent event(isolate, ServiceEvent::kEmbedder);
+ event.set_embedder_kind(event_kind);
+ event.set_embedder_stream_id(stream_id);
+ event.set_bytes(bytes, bytes_len);
+ Service::HandleEvent(&event);
+}
+
+
class ContainsAddressVisitor : public FindObjectVisitor {
public:
ContainsAddressVisitor(Isolate* isolate, uword addr)

Powered by Google App Engine
This is Rietveld 408576698