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

Side by Side 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, 4 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
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/debugger.h"
6 #include "vm/heap_histogram.h"
5 #include "vm/isolate.h" 7 #include "vm/isolate.h"
6 #include "vm/message.h" 8 #include "vm/message.h"
7 #include "vm/object.h" 9 #include "vm/object.h"
8 #include "vm/port.h" 10 #include "vm/port.h"
9 #include "vm/service.h" 11 #include "vm/service.h"
10 12
11 namespace dart { 13 namespace dart {
12 14
15 typedef RawString* (*ServiceMessageHandler)(Isolate* isolate);
16
17 struct ServiceMessageHandlerEntry {
18 const char* command;
19 ServiceMessageHandler handler;
20 };
21
22 static ServiceMessageHandler FindServiceMessageHandler(const char* command);
23
24
13 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 25 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
14 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 26 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
15 return reinterpret_cast<uint8_t*>(new_ptr); 27 return reinterpret_cast<uint8_t*>(new_ptr);
16 } 28 }
17 29
18 30
19 static void PostReply(const String& reply, Dart_Port reply_port) { 31 static void PostReply(const String& reply, Dart_Port reply_port) {
20 uint8_t* data = NULL; 32 uint8_t* data = NULL;
21 MessageWriter writer(&data, &allocator); 33 MessageWriter writer(&data, &allocator);
22 writer.WriteMessage(reply); 34 writer.WriteMessage(reply);
23 PortMap::PostMessage(new Message(reply_port, Message::kIllegalPort, data, 35 PortMap::PostMessage(new Message(reply_port, Message::kIllegalPort, data,
24 writer.BytesWritten(), 36 writer.BytesWritten(),
25 Message::kNormalPriority)); 37 Message::kNormalPriority));
26 } 38 }
27 39
28 40
29 static RawString* HandleIdMessage(Isolate* isolate, Dart_Port reply_port) { 41 void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port,
42 const Instance& msg) {
43 ASSERT(isolate != NULL);
44 ASSERT(reply_port != ILLEGAL_PORT);
45 ASSERT(!msg.IsNull());
46 // Message is a list with three entries.
47 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.
48
49 {
50 StackZone zone(isolate);
51 HANDLESCOPE(isolate);
52 const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
53 ASSERT(message.Length() == 3);
54
55 GrowableObjectArray& path = GrowableObjectArray::Handle();
56 GrowableObjectArray& option_keys = GrowableObjectArray::Handle();
57 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
58 path ^= message.At(0);
59 option_keys ^= message.At(1);
60 option_values ^= message.At(2);
61
62 ASSERT(!path.IsNull());
63 ASSERT(!option_keys.IsNull());
64 ASSERT(!option_values.IsNull());
65 // Path always has at least one entry in it.
66 ASSERT(path.Length() > 0);
67 // Same number of option keys as values.
68 ASSERT(option_keys.Length() == option_values.Length());
69
70 String& pathSegment = String::Handle();
71 pathSegment ^= path.At(0);
72 ASSERT(!pathSegment.IsNull());
73
74 ServiceMessageHandler handler =
75 FindServiceMessageHandler(pathSegment.ToCString());
76 String& reply = String::Handle();
77 reply ^= handler(isolate);
78 ASSERT(!reply.IsNull());
79 PostReply(reply, reply_port);
80 }
81 }
82
83
84 static RawString* HandleName(Isolate* isolate) {
30 TextBuffer buffer(256); 85 TextBuffer buffer(256);
31 buffer.Printf("{ \"id\": \"%s\" }", isolate->name()); 86 JSONStream js(&buffer);
87 js.OpenObject();
88 js.PrintProperty("type", "IsolateName");
89 js.PrintProperty("id", static_cast<intptr_t>(isolate->main_port()));
90 js.PrintProperty("name", isolate->name());
91 js.CloseObject();
32 return String::New(buffer.buf()); 92 return String::New(buffer.buf());
33 } 93 }
34 94
35 95
36 void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port, 96 RawString* HandleStackTrace(Isolate* isolate) {
37 const Instance& message) { 97 TextBuffer buffer(256);
38 ASSERT(isolate != NULL); 98 JSONStream js(&buffer);
39 ASSERT(reply_port != ILLEGAL_PORT); 99 DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
40 ASSERT(!message.IsNull()); 100 js.OpenObject();
41 ASSERT(message.IsString()); 101 js.PrintProperty("type", "StackTrace");
102 js.OpenArray("members");
103 intptr_t n_frames = stack->Length();
104 String& url = String::Handle();
105 String& function = String::Handle();
106 for (int i = 0; i < n_frames; i++) {
107 ActivationFrame* frame = stack->ActivationFrameAt(i);
108 url ^= frame->SourceUrl();
109 function ^= frame->function().UserVisibleName();
110 js.OpenObject();
111 js.PrintProperty("name", function.ToCString());
112 js.PrintProperty("url", url.ToCString());
113 js.PrintProperty("line", frame->LineNumber());
114 js.PrintProperty("function", frame->function());
115 js.PrintProperty("code", frame->code());
116 js.CloseObject();
117 }
118 js.CloseArray();
119 js.CloseObject();
120 return String::New(buffer.buf());
121 }
42 122
43 String& reply = String::Handle();
44 123
45 // For now, assume service message is always an id check. 124 RawString* HandleObjectHistogram(Isolate* isolate) {
46 reply = HandleIdMessage(isolate, reply_port); 125 TextBuffer buffer(256);
126 JSONStream js(&buffer);
127 ObjectHistogram* histogram = Isolate::Current()->object_histogram();
128 if (histogram == NULL) {
129 js.OpenObject();
130 js.PrintProperty("type", "ObjectHistogram");
131 js.PrintProperty("error", "Run with --print_object_histogram");
132 js.CloseObject();
133 return String::New(buffer.buf());
134 }
135 histogram->PrintToJSONStream(&js);
136 return String::New(buffer.buf());
137 }
47 138
48 ASSERT(!reply.IsNull());
49 139
50 PostReply(reply, reply_port); 140 static ServiceMessageHandlerEntry __message_handlers[] = {
141 { "name", HandleName },
142 { "stacktrace", HandleStackTrace },
143 { "objecthistogram", HandleObjectHistogram},
144 };
145
146
147 static RawString* HandleFallthrough(Isolate* isolate) {
148 TextBuffer buffer(256);
149 JSONStream js(&buffer);
150 js.OpenObject();
151 js.PrintProperty("type", "error");
152 js.PrintProperty("text", "request not supported.");
153 js.CloseObject();
154 return String::New(buffer.buf());
155 }
156
157
158 static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
159 intptr_t num_message_handlers = sizeof(__message_handlers) /
160 sizeof(__message_handlers[0]);
161 for (intptr_t i = 0; i < num_message_handlers; i++) {
162 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
163 if (!strcmp(command, entry.command)) {
164 return entry.handler;
165 }
166 }
167 return HandleFallthrough;
51 } 168 }
52 169
53 } // namespace dart 170 } // namespace dart
171
siva 2013/08/01 18:16:18 Extra blank line.
Cutch 2013/08/01 22:22:04 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698