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

Unified Diff: runtime/vm/service.cc

Issue 19870006: Support stacktrace and objecthistogram service commands (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 6a27c19c85e6d08c67202e44d3ffb31221c8ea4b..f65b5070a9fc6f022abd0882259349ea9a82e67a 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+#include "vm/debugger.h"
+#include "vm/heap_histogram.h"
#include "vm/isolate.h"
#include "vm/message.h"
#include "vm/object.h"
@@ -10,6 +12,16 @@
namespace dart {
+typedef RawString* (*ServiceMessageHandler)(Isolate* isolate);
+
+struct ServiceMessageHandlerEntry {
+ const char* command;
+ ServiceMessageHandler handler;
+};
+
+static ServiceMessageHandler FindServiceMessageHandler(const char* command);
+
+
static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
return reinterpret_cast<uint8_t*>(new_ptr);
@@ -26,28 +38,134 @@ static void PostReply(const String& reply, Dart_Port reply_port) {
}
-static RawString* HandleIdMessage(Isolate* isolate, Dart_Port reply_port) {
+void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port,
+ const Instance& msg) {
+ ASSERT(isolate != NULL);
+ ASSERT(reply_port != ILLEGAL_PORT);
+ ASSERT(!msg.IsNull());
+ // Message is a list with three entries.
+ ASSERT(msg.IsGrowableObjectArray());
siva 2013/08/01 18:16:18 probably would become IsObjectArray() if you make
siva 2013/08/01 18:16:18 would become IsObjectArray() if you made the sugge
Cutch 2013/08/01 22:22:04 Done.
+
+ {
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
+ ASSERT(message.Length() == 3);
+
+ GrowableObjectArray& path = GrowableObjectArray::Handle();
+ GrowableObjectArray& option_keys = GrowableObjectArray::Handle();
+ GrowableObjectArray& option_values = GrowableObjectArray::Handle();
siva 2013/08/01 18:16:18 option_keys and option_values seem to be only used
Cutch 2013/08/01 22:22:04 option_keys and option_values will be used in a fu
+ path ^= message.At(0);
+ option_keys ^= message.At(1);
+ option_values ^= message.At(2);
+
+ ASSERT(!path.IsNull());
+ ASSERT(!option_keys.IsNull());
+ ASSERT(!option_values.IsNull());
+ // Path always has at least one entry in it.
+ ASSERT(path.Length() > 0);
+ // Same number of option keys as values.
+ ASSERT(option_keys.Length() == option_values.Length());
+
+ String& pathSegment = String::Handle();
+ pathSegment ^= path.At(0);
+ ASSERT(!pathSegment.IsNull());
+
+ ServiceMessageHandler handler =
+ FindServiceMessageHandler(pathSegment.ToCString());
+ String& reply = String::Handle();
+ reply ^= handler(isolate);
+ ASSERT(!reply.IsNull());
+ PostReply(reply, reply_port);
+ }
+}
+
+
+static RawString* HandleName(Isolate* isolate) {
TextBuffer buffer(256);
- buffer.Printf("{ \"id\": \"%s\" }", isolate->name());
+ JSONStream js(&buffer);
+ js.OpenObject();
+ js.PrintProperty("type", "IsolateName");
+ js.PrintProperty("id", static_cast<intptr_t>(isolate->main_port()));
+ js.PrintProperty("name", isolate->name());
+ js.CloseObject();
return String::New(buffer.buf());
}
-void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port,
- const Instance& message) {
- ASSERT(isolate != NULL);
- ASSERT(reply_port != ILLEGAL_PORT);
- ASSERT(!message.IsNull());
- ASSERT(message.IsString());
+RawString* HandleStackTrace(Isolate* isolate) {
+ TextBuffer buffer(256);
+ JSONStream js(&buffer);
+ DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
+ js.OpenObject();
+ js.PrintProperty("type", "StackTrace");
+ js.OpenArray("members");
+ intptr_t n_frames = stack->Length();
+ String& url = String::Handle();
+ String& function = String::Handle();
+ for (int i = 0; i < n_frames; i++) {
+ ActivationFrame* frame = stack->ActivationFrameAt(i);
+ url ^= frame->SourceUrl();
+ function ^= frame->function().UserVisibleName();
+ js.OpenObject();
+ js.PrintProperty("name", function.ToCString());
+ js.PrintProperty("url", url.ToCString());
+ js.PrintProperty("line", frame->LineNumber());
+ js.PrintProperty("function", frame->function());
+ js.PrintProperty("code", frame->code());
+ js.CloseObject();
+ }
+ js.CloseArray();
+ js.CloseObject();
+ return String::New(buffer.buf());
+}
+
+
+RawString* HandleObjectHistogram(Isolate* isolate) {
+ TextBuffer buffer(256);
+ JSONStream js(&buffer);
+ ObjectHistogram* histogram = Isolate::Current()->object_histogram();
+ if (histogram == NULL) {
+ js.OpenObject();
+ js.PrintProperty("type", "ObjectHistogram");
+ js.PrintProperty("error", "Run with --print_object_histogram");
+ js.CloseObject();
+ return String::New(buffer.buf());
+ }
+ histogram->PrintToJSONStream(&js);
+ return String::New(buffer.buf());
+}
+
+
+static ServiceMessageHandlerEntry __message_handlers[] = {
+ { "name", HandleName },
+ { "stacktrace", HandleStackTrace },
+ { "objecthistogram", HandleObjectHistogram},
+};
- String& reply = String::Handle();
- // For now, assume service message is always an id check.
- reply = HandleIdMessage(isolate, reply_port);
+static RawString* HandleFallthrough(Isolate* isolate) {
+ TextBuffer buffer(256);
+ JSONStream js(&buffer);
+ js.OpenObject();
+ js.PrintProperty("type", "error");
+ js.PrintProperty("text", "request not supported.");
+ js.CloseObject();
+ return String::New(buffer.buf());
+}
- ASSERT(!reply.IsNull());
- PostReply(reply, reply_port);
+static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
+ intptr_t num_message_handlers = sizeof(__message_handlers) /
+ sizeof(__message_handlers[0]);
+ for (intptr_t i = 0; i < num_message_handlers; i++) {
+ const ServiceMessageHandlerEntry& entry = __message_handlers[i];
+ if (!strcmp(command, entry.command)) {
+ return entry.handler;
+ }
+ }
+ return HandleFallthrough;
}
} // namespace dart
+
siva 2013/08/01 18:16:18 Extra blank line.
Cutch 2013/08/01 22:22:04 Done.

Powered by Google App Engine
This is Rietveld 408576698