OLD | NEW |
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/service.h" | 5 #include "vm/service.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 return true; | 927 return true; |
928 } | 928 } |
929 } | 929 } |
930 return false; | 930 return false; |
931 } else { | 931 } else { |
932 return !obj.IsInstance(); | 932 return !obj.IsInstance(); |
933 } | 933 } |
934 } | 934 } |
935 | 935 |
936 | 936 |
| 937 static bool HandleRetainingPath(Isolate* isolate, |
| 938 Object* obj, |
| 939 intptr_t limit, |
| 940 JSONStream* js) { |
| 941 ObjectGraph graph(isolate); |
| 942 Array& path = Array::Handle(Array::New(limit * 2)); |
| 943 intptr_t length = graph.RetainingPath(obj, path); |
| 944 JSONObject jsobj(js); |
| 945 jsobj.AddProperty("type", "RetainingPath"); |
| 946 jsobj.AddProperty("id", "retaining_path"); |
| 947 jsobj.AddProperty("length", length); |
| 948 JSONArray elements(&jsobj, "elements"); |
| 949 Object& element = Object::Handle(); |
| 950 Object& parent = Object::Handle(); |
| 951 Smi& offset_from_parent = Smi::Handle(); |
| 952 Class& parent_class = Class::Handle(); |
| 953 Array& parent_field_map = Array::Handle(); |
| 954 Field& field = Field::Handle(); |
| 955 limit = Utils::Minimum(limit, length); |
| 956 for (intptr_t i = 0; i < limit; ++i) { |
| 957 JSONObject jselement(&elements); |
| 958 element = path.At(i * 2); |
| 959 jselement.AddProperty("index", i); |
| 960 jselement.AddProperty("value", element); |
| 961 // Interpret the word offset from parent as list index or instance field. |
| 962 // TODO(koda): User-friendly interpretation for map entries. |
| 963 offset_from_parent ^= path.At((i * 2) + 1); |
| 964 int parent_i = i + 1; |
| 965 if (parent_i < limit) { |
| 966 parent = path.At(parent_i * 2); |
| 967 if (parent.IsArray()) { |
| 968 intptr_t element_index = offset_from_parent.Value() - |
| 969 (Array::element_offset(0) >> kWordSizeLog2); |
| 970 jselement.AddProperty("parentListIndex", element_index); |
| 971 } else if (parent.IsInstance()) { |
| 972 parent_class ^= parent.clazz(); |
| 973 parent_field_map = parent_class.OffsetToFieldMap(); |
| 974 intptr_t offset = offset_from_parent.Value(); |
| 975 if (offset > 0 && offset < parent_field_map.Length()) { |
| 976 field ^= parent_field_map.At(offset); |
| 977 jselement.AddProperty("parentField", field); |
| 978 } |
| 979 } |
| 980 } |
| 981 } |
| 982 return true; |
| 983 } |
| 984 |
937 // Takes an Object* only because RetainingPath temporarily clears it. | 985 // Takes an Object* only because RetainingPath temporarily clears it. |
938 static bool HandleInstanceCommands(Isolate* isolate, | 986 static bool HandleInstanceCommands(Isolate* isolate, |
939 Object* obj, | 987 Object* obj, |
940 JSONStream* js, | 988 JSONStream* js, |
941 intptr_t arg_pos) { | 989 intptr_t arg_pos) { |
942 ASSERT(js->num_arguments() > arg_pos); | 990 ASSERT(js->num_arguments() > arg_pos); |
943 const char* action = js->GetArgument(arg_pos); | 991 const char* action = js->GetArgument(arg_pos); |
944 if (strcmp(action, "eval") == 0) { | 992 if (strcmp(action, "eval") == 0) { |
945 if (js->num_arguments() > (arg_pos + 1)) { | 993 if (js->num_arguments() > (arg_pos + 1)) { |
946 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n", | 994 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n", |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 const Object& result = Object::Handle(Integer::New(retained_size)); | 1033 const Object& result = Object::Handle(Integer::New(retained_size)); |
986 result.PrintJSON(js, true); | 1034 result.PrintJSON(js, true); |
987 return true; | 1035 return true; |
988 } else if (strcmp(action, "retaining_path") == 0) { | 1036 } else if (strcmp(action, "retaining_path") == 0) { |
989 intptr_t limit; | 1037 intptr_t limit; |
990 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { | 1038 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { |
991 PrintError(js, "retaining_path expects a 'limit' option\n", | 1039 PrintError(js, "retaining_path expects a 'limit' option\n", |
992 js->num_arguments()); | 1040 js->num_arguments()); |
993 return true; | 1041 return true; |
994 } | 1042 } |
995 ObjectGraph graph(isolate); | 1043 return HandleRetainingPath(isolate, obj, limit, js); |
996 Array& path = Array::Handle(Array::New(limit)); | |
997 intptr_t length = graph.RetainingPath(obj, path); | |
998 JSONObject jsobj(js); | |
999 jsobj.AddProperty("type", "RetainingPath"); | |
1000 jsobj.AddProperty("id", "retaining_path"); | |
1001 jsobj.AddProperty("length", length); | |
1002 JSONArray elements(&jsobj, "elements"); | |
1003 for (intptr_t i = 0; i < path.Length() && i < length; ++i) { | |
1004 JSONObject jselement(&elements); | |
1005 Object& element = Object::Handle(); | |
1006 element = path.At(i); | |
1007 jselement.AddProperty("index", i); | |
1008 jselement.AddProperty("value", element); | |
1009 } | |
1010 return true; | |
1011 } | 1044 } |
1012 | 1045 |
1013 PrintError(js, "unrecognized action '%s'\n", action); | 1046 PrintError(js, "unrecognized action '%s'\n", action); |
1014 return true; | 1047 return true; |
1015 } | 1048 } |
1016 | 1049 |
1017 | 1050 |
1018 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, | 1051 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, |
1019 JSONStream* js) { | 1052 JSONStream* js) { |
1020 intptr_t id; | 1053 intptr_t id; |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 while (current != NULL) { | 2349 while (current != NULL) { |
2317 if (strcmp(name, current->name()) == 0) { | 2350 if (strcmp(name, current->name()) == 0) { |
2318 return current; | 2351 return current; |
2319 } | 2352 } |
2320 current = current->next(); | 2353 current = current->next(); |
2321 } | 2354 } |
2322 return NULL; | 2355 return NULL; |
2323 } | 2356 } |
2324 | 2357 |
2325 } // namespace dart | 2358 } // namespace dart |
OLD | NEW |