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

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
Index: runtime/vm/service.cc
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index cff1f2819d34e85f5dbb8a2a6533170a449116f1..54f5a5b9d2ccfef7a78b28b82000cb3a3e4238e3 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;
@@ -290,8 +312,29 @@ static void HandleClassesClosures(Isolate* isolate, const Class& cls,
}
+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 " is not a function.", id);
+ return;
+ }
+ func.PrintToJSONStream(js, false);
+}
+
+
static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
- JSONStream* js) {
+ JSONStream* js, bool implicit_closure) {
const Array& functions =
Array::Handle(cls.functions());
intptr_t id;
@@ -299,12 +342,28 @@ static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
PrintError(js, "Command too long");
return;
}
- CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
- js->GetArgument(3), id, js);
+ if (implicit_closure) {
+ CHECK_COLLECTION_ID_BOUNDS("implicit_closures", functions.Length(),
+ js->GetArgument(3), id, js);
+ } else {
+ 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 (!implicit_closure) {
+ function.PrintToJSONStream(js, false);
+ return;
+ }
+ if (!function.HasImplicitClosureFunction()) {
+ PrintError(js, "Function %" Pd " does not have an implicit closure.", id);
+ return;
+ }
+ Function& closure_function = Function::Handle();
+ closure_function ^= function.ImplicitClosureFunction();
+ ASSERT(!closure_function.IsNull());
+ closure_function.PrintToJSONStream(js, false);
}
@@ -354,7 +413,11 @@ static void HandleClasses(Isolate* isolate, JSONStream* js) {
} else if (!strcmp(second, "fields")) {
HandleClassesFields(isolate, cls, js);
} else if (!strcmp(second, "functions")) {
- HandleClassesFunctions(isolate, cls, js);
+ HandleClassesFunctions(isolate, cls, js, false);
+ } else if (!strcmp(second, "implicit_closures")) {
+ HandleClassesFunctions(isolate, cls, js, true);
+ } else if (!strcmp(second, "dispatchers")) {
+ HandleClassesDispatchers(isolate, cls, js);
} else {
PrintError(js, "Invalid sub collection %s", second);
}
@@ -521,9 +584,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 +616,7 @@ static ServiceMessageHandlerEntry __message_handlers[] = {
{ "name", HandleName },
{ "objecthistogram", HandleObjectHistogram},
{ "objects", HandleObjects },
+ { "profile", HandleProfile },
{ "scripts", HandleScripts },
{ "stacktrace", HandleStackTrace },
};

Powered by Google App Engine
This is Rietveld 408576698