Chromium Code Reviews| Index: runtime/vm/service.cc |
| =================================================================== |
| --- runtime/vm/service.cc (revision 32027) |
| +++ runtime/vm/service.cc (working copy) |
| @@ -22,6 +22,7 @@ |
| #include "vm/object_store.h" |
| #include "vm/port.h" |
| #include "vm/profiler.h" |
| +#include "vm/stack_frame.h" |
| #include "vm/symbols.h" |
| @@ -569,13 +570,15 @@ |
| 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); |
| + if (path.Length() > 0) { |
| + pathSegment ^= path.At(0); |
| + } else { |
| + pathSegment ^= Symbols::Empty().raw(); |
| + } |
| ASSERT(!pathSegment.IsNull()); |
| IsolateMessageHandler handler = |
| @@ -598,33 +601,92 @@ |
| } |
| -static bool HandleName(Isolate* isolate, JSONStream* js) { |
| +static bool HandleIsolate(Isolate* isolate, JSONStream* js) { |
| JSONObject jsobj(js); |
| - jsobj.AddProperty("type", "IsolateName"); |
| - jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); |
| - jsobj.AddProperty("name", isolate->name()); |
| + jsobj.AddProperty("type", "Isolate"); |
| + jsobj.AddPropertyF("id", "isolates/%" Pd "", |
| + static_cast<intptr_t>(isolate->main_port())); |
| + jsobj.AddPropertyF("name", "%" Pd "", |
| + static_cast<intptr_t>(isolate->main_port())); |
|
Cutch
2014/01/28 19:32:51
Does it make sense to move most of this into Isola
turnidge
2014/01/28 23:18:55
Yes, done.
|
| + IsolateSpawnState* state = isolate->spawn_state(); |
| + if (state != NULL) { |
| + const Object& entry = Object::Handle(isolate, state->ResolveFunction()); |
| + if (!entry.IsNull() && entry.IsFunction()) { |
| + Function& func = Function::Handle(isolate); |
| + func ^= entry.raw(); |
| + jsobj.AddProperty("entry", func); |
| + } |
| + } |
| + { |
| + Heap* heap = isolate->heap(); |
| + JSONObject jsheap(&jsobj, "heap"); |
| + jsheap.AddProperty("usedNew", heap->UsedInWords(Heap::kNew)); |
| + jsheap.AddProperty("capacityNew", heap->CapacityInWords(Heap::kNew)); |
| + jsheap.AddProperty("usedOld", heap->UsedInWords(Heap::kOld)); |
| + jsheap.AddProperty("capacityOld", heap->CapacityInWords(Heap::kOld)); |
| + } |
| + |
| + DartFrameIterator iterator; |
| + StackFrame* top_frame = iterator.NextFrame(); |
|
Cutch
2014/01/28 19:32:51
Similiarly StackFrame::PrintToJSONStream?
turnidge
2014/01/28 23:18:55
I've updated all of the stack display code to use
|
| + if (top_frame) { |
| + JSONObject jsframe(&jsobj, "topFrame"); |
| + const Code& code = Code::Handle(top_frame->LookupDartCode()); |
| + const Function& top_function = Function::Handle(code.function()); |
| + const Script& script = Script::Handle(top_function.script()); |
| + const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); |
| + intptr_t line, column; |
| + script.GetTokenLocation(token_pos, &line, &column); |
| + String& line_string = String::Handle(script.GetLine(line)); |
| + |
| + jsobj.AddProperty("script", script); |
| + jsobj.AddProperty("line", line); |
| + jsobj.AddProperty("lineString", line_string.ToCString()); |
| + jsobj.AddProperty("function", top_function); |
| + jsobj.AddProperty("code", code); |
| + } |
| + |
| + const Library& lib = |
| + Library::Handle(isolate->object_store()->root_library()); |
| + jsobj.AddProperty("rootLib", lib); |
| + |
| + isolate->timer_list().PrintTimersToJSONProperty(&jsobj); |
| return true; |
| } |
| static bool HandleStackTrace(Isolate* isolate, JSONStream* js) { |
| + if (js->num_arguments() > 1) { |
| + PrintError(js, "Command too long"); |
| + return true; |
| + } |
| DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
| JSONObject jsobj(js); |
| jsobj.AddProperty("type", "StackTrace"); |
| JSONArray jsarr(&jsobj, "members"); |
| - intptr_t n_frames = stack->Length(); |
| - String& function = String::Handle(); |
| + intptr_t num_frames = stack->Length(); |
| Script& script = Script::Handle(); |
| - for (int i = 0; i < n_frames; i++) { |
| + for (intptr_t i = 0; i < num_frames; i++) { |
| ActivationFrame* frame = stack->FrameAt(i); |
| script ^= frame->SourceScript(); |
| - function ^= frame->function().UserVisibleName(); |
| JSONObject jsobj(&jsarr); |
| - jsobj.AddProperty("name", function.ToCString()); |
| jsobj.AddProperty("script", script); |
| jsobj.AddProperty("line", frame->LineNumber()); |
| jsobj.AddProperty("function", frame->function()); |
| jsobj.AddProperty("code", frame->code()); |
| + jsobj.AddProperty("depth", i); |
| + { |
| + JSONArray jsvars(&jsobj, "vars"); |
| + const int num_vars = frame->NumLocalVariables(); |
| + for (intptr_t v = 0; v < num_vars; v++) { |
| + JSONObject jsvar(&jsvars); |
| + String& var_name = String::Handle(); |
| + Instance& var_value = Instance::Handle(); |
| + intptr_t unused; |
| + frame->VariableAt(v, &var_name, &unused, &unused, &var_value); |
| + jsvar.AddProperty("name", var_name.ToCString()); |
| + jsvar.AddProperty("value", var_value); |
| + } |
| + } |
| } |
| return true; |
| } |
| @@ -865,18 +927,6 @@ |
| } |
| -static bool HandleLibrary(Isolate* isolate, JSONStream* js) { |
| - if (js->num_arguments() == 1) { |
| - const Library& lib = |
| - Library::Handle(isolate->object_store()->root_library()); |
| - lib.PrintToJSONStream(js, false); |
| - return true; |
| - } |
| - PrintError(js, "Command too long"); |
| - return true; |
| -} |
| - |
| - |
| static bool HandleLibraries(Isolate* isolate, JSONStream* js) { |
| // TODO(johnmccutchan): Support fields and functions on libraries. |
| REQUIRE_COLLECTION_ID("libraries"); |
| @@ -897,10 +947,58 @@ |
| static bool HandleObjects(Isolate* isolate, JSONStream* js) { |
| REQUIRE_COLLECTION_ID("objects"); |
| ASSERT(js->num_arguments() >= 2); |
| + const char* arg = js->GetArgument(1); |
| + |
| + // TODO(turnidge): Handle <optimized out> the same way as other |
| + // special nulls. |
| + if (strcmp(arg, "null") == 0 || |
| + strcmp(arg, "not-initialized") == 0 || |
| + strcmp(arg, "being-initialized") == 0) { |
| + Object::null_object().PrintToJSONStream(js, false); |
| + return true; |
| + |
|
Cutch
2014/01/28 19:32:51
Remove extra blank line.
|
| + } else if (strcmp(arg, "int") == 0) { |
| + if (js->num_arguments() < 3) { |
| + PrintError(js, "expected 3 arguments but found %" Pd "\n", |
| + js->num_arguments()); |
| + return true; |
| + } |
| + int64_t value = 0; |
| + if (!OS::StringToInt64(js->GetArgument(2), &value) || |
| + !Smi::IsValid64(value)) { |
| + PrintError(js, "integer value too large\n", |
| + js->num_arguments()); |
| + return true; |
| + } |
| + const Integer& obj = |
| + Integer::Handle(isolate, Smi::New(static_cast<intptr_t>(value))); |
| + obj.PrintToJSONStream(js, false); |
| + return true; |
| + |
|
Cutch
2014/01/28 19:32:51
Remove extra blank line.
|
| + } else if (strcmp(arg, "bool") == 0) { |
| + if (js->num_arguments() < 3) { |
| + PrintError(js, "expected 3 arguments but found %" Pd "\n", |
| + js->num_arguments()); |
| + return true; |
| + } |
| + const char* value_str = js->GetArgument(2); |
| + bool value = false; |
| + if (strcmp(value_str, "false") == 0) { |
| + value = false; |
| + } else if (strcmp(value_str, "true") == 0) { |
| + value = true; |
| + } else { |
| + PrintError(js, "expected 'true' or 'false' but found %s\n", value_str); |
| + return true; |
| + } |
| + Bool::Get(value).PrintToJSONStream(js, false); |
| + return true; |
| + } |
| + |
| ObjectIdRing* ring = isolate->object_id_ring(); |
| ASSERT(ring != NULL); |
| intptr_t id = -1; |
| - if (!GetIntegerId(js->GetArgument(1), &id)) { |
| + if (!GetIntegerId(arg, &id)) { |
| Object::null_object().PrintToJSONStream(js, false); |
| return true; |
| } |
| @@ -1058,14 +1156,13 @@ |
| static IsolateMessageHandlerEntry isolate_handlers[] = { |
| { "_echo", HandleIsolateEcho }, |
| + { "", HandleIsolate }, |
| { "allocationprofile", HandleAllocationProfile }, |
| { "classes", HandleClasses }, |
| { "code", HandleCode }, |
| { "coverage", HandleCoverage }, |
| { "debug", HandleDebug }, |
| { "libraries", HandleLibraries }, |
| - { "library", HandleLibrary }, |
| - { "name", HandleName }, |
| { "objecthistogram", HandleObjectHistogram}, |
| { "objects", HandleObjects }, |
| { "profile", HandleProfile }, |