Chromium Code Reviews| 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.
|