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

Unified Diff: runtime/vm/service.cc

Issue 100103011: Changes to support dprof and Observatory profiler UIs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 12 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
« no previous file with comments | « runtime/vm/profiler_test.cc ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/service.cc
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index cff1f2819d34e85f5dbb8a2a6533170a449116f1..fe8aaa1b197084bb3e0518bcb6461d126f602382 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -14,6 +14,7 @@
#include "vm/object_id_ring.h"
#include "vm/object_store.h"
#include "vm/port.h"
+#include "vm/profiler.h"
namespace dart {
@@ -251,7 +252,7 @@ static void HandleEcho(Isolate* isolate, JSONStream* js) {
}
-static bool GetIntegerId(const char* s, intptr_t* id) {
+static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) {
if ((s == NULL) || (*s == '\0')) {
// Empty string.
return false;
@@ -262,7 +263,28 @@ static bool GetIntegerId(const char* s, intptr_t* id) {
}
intptr_t r = 0;
char* end_ptr = NULL;
- r = strtol(s, &end_ptr, 10);
+ r = strtol(s, &end_ptr, base);
+ if (end_ptr == s) {
+ // String was not advanced at all, cannot be valid.
+ return false;
+ }
+ *id = r;
+ return true;
+}
+
+
+static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) {
+ if ((s == NULL) || (*s == '\0')) {
+ // Empty string.
+ return false;
+ }
+ if (id == NULL) {
+ // No id pointer.
+ return false;
+ }
+ uintptr_t r = 0;
+ char* end_ptr = NULL;
+ r = strtoul(s, &end_ptr, base);
if (end_ptr == s) {
// String was not advanced at all, cannot be valid.
return false;
@@ -274,54 +296,104 @@ static bool GetIntegerId(const char* s, intptr_t* id) {
static void HandleClassesClosures(Isolate* isolate, const Class& cls,
JSONStream* js) {
- const GrowableObjectArray& closures =
- GrowableObjectArray::Handle(cls.closures());
intptr_t id;
if (js->num_arguments() > 4) {
PrintError(js, "Command too long");
return;
}
- CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3),
- id, js);
- Function& function = Function::Handle();
- function ^= closures.At(id);
- ASSERT(!function.IsNull());
- function.PrintToJSONStream(js, false);
+ if (!GetIntegerId(js->GetArgument(3), &id)) {
+ PrintError(js, "Must specify collection object id: closures/id");
+ return;
+ }
+ Function& func = Function::Handle();
+ func ^= cls.ClosureFunctionFromIndex(id);
+ if (func.IsNull()) {
+ PrintError(js, "Closure function %" Pd " not found", id);
+ return;
+ }
+ func.PrintToJSONStream(js, false);
+}
+
+
+static void HandleClassesDispatchers(Isolate* isolate, const Class& cls,
+ JSONStream* js) {
+ intptr_t id;
+ if (js->num_arguments() > 4) {
+ PrintError(js, "Command too long");
+ return;
+ }
+ if (!GetIntegerId(js->GetArgument(3), &id)) {
+ PrintError(js, "Must specify collection object id: dispatchers/id");
+ return;
+ }
+ Function& func = Function::Handle();
+ func ^= cls.InvocationDispatcherFunctionFromIndex(id);
+ if (func.IsNull()) {
+ PrintError(js, "Dispatcher %" Pd " not found", id);
+ return;
+ }
+ func.PrintToJSONStream(js, false);
}
static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
JSONStream* js) {
- const Array& functions =
- Array::Handle(cls.functions());
intptr_t id;
if (js->num_arguments() > 4) {
PrintError(js, "Command too long");
return;
}
- CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
- js->GetArgument(3), id, js);
- Function& function = Function::Handle();
- function ^= functions.At(id);
- ASSERT(!function.IsNull());
- function.PrintToJSONStream(js, false);
+ if (!GetIntegerId(js->GetArgument(3), &id)) {
+ PrintError(js, "Must specify collection object id: functions/id");
+ return;
+ }
+ Function& func = Function::Handle();
+ func ^= cls.FunctionFromIndex(id);
+ if (func.IsNull()) {
+ PrintError(js, "Function %" Pd " not found", id);
+ return;
+ }
+ func.PrintToJSONStream(js, false);
+}
+
+
+static void HandleClassesImplicitClosures(Isolate* isolate, const Class& cls,
+ JSONStream* js) {
+ intptr_t id;
+ if (js->num_arguments() > 4) {
+ PrintError(js, "Command too long");
+ return;
+ }
+ if (!GetIntegerId(js->GetArgument(3), &id)) {
+ PrintError(js, "Must specify collection object id: implicit_closures/id");
+ return;
+ }
+ Function& func = Function::Handle();
+ func ^= cls.ImplicitClosureFunctionFromIndex(id);
+ if (func.IsNull()) {
+ PrintError(js, "Implicit closure function %" Pd " not found", id);
+ return;
+ }
+ func.PrintToJSONStream(js, false);
}
static void HandleClassesFields(Isolate* isolate, const Class& cls,
JSONStream* js) {
- const Array& fields =
- Array::Handle(cls.fields());
intptr_t id;
if (js->num_arguments() > 4) {
PrintError(js, "Command too long");
return;
}
- CHECK_COLLECTION_ID_BOUNDS("fields", fields.Length(), js->GetArgument(3),
- id, js);
- Field& field = Field::Handle();
- field ^= fields.At(id);
- ASSERT(!field.IsNull());
+ if (!GetIntegerId(js->GetArgument(3), &id)) {
+ PrintError(js, "Must specify collection object id: fields/id");
+ return;
+ }
+ Field& field = Field::Handle(cls.FieldFromIndex(id));
+ if (field.IsNull()) {
+ PrintError(js, "Field %" Pd " not found", id);
+ return;
+ }
field.PrintToJSONStream(js, false);
}
@@ -355,6 +427,10 @@ static void HandleClasses(Isolate* isolate, JSONStream* js) {
HandleClassesFields(isolate, cls, js);
} else if (!strcmp(second, "functions")) {
HandleClassesFunctions(isolate, cls, js);
+ } else if (!strcmp(second, "implicit_closures")) {
+ HandleClassesImplicitClosures(isolate, cls, js);
+ } else if (!strcmp(second, "dispatchers")) {
+ HandleClassesDispatchers(isolate, cls, js);
} else {
PrintError(js, "Invalid sub collection %s", second);
}
@@ -521,9 +597,31 @@ static void HandleCpu(Isolate* isolate, JSONStream* js) {
}
+static void HandleCode(Isolate* isolate, JSONStream* js) {
+ REQUIRE_COLLECTION_ID("code");
+ uintptr_t pc;
+ if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
+ PrintError(js, "Must specify code address: code/c0deadd0.");
+ return;
+ }
+ Code& code = Code::Handle(Code::LookupCode(pc));
+ if (code.IsNull()) {
+ PrintError(js, "Could not find code at %" Px "", pc);
+ return;
+ }
+ code.PrintToJSONStream(js, false);
+}
+
+
+static void HandleProfile(Isolate* isolate, JSONStream* js) {
+ Profiler::PrintToJSONStream(isolate, js, true);
+}
+
+
static ServiceMessageHandlerEntry __message_handlers[] = {
{ "_echo", HandleEcho },
{ "classes", HandleClasses },
+ { "code", HandleCode },
{ "cpu", HandleCpu },
{ "debug", HandleDebug },
{ "libraries", HandleLibraries },
@@ -531,6 +629,7 @@ static ServiceMessageHandlerEntry __message_handlers[] = {
{ "name", HandleName },
{ "objecthistogram", HandleObjectHistogram},
{ "objects", HandleObjects },
+ { "profile", HandleProfile },
{ "scripts", HandleScripts },
{ "stacktrace", HandleStackTrace },
};
« no previous file with comments | « runtime/vm/profiler_test.cc ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698