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 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 return true; | 915 return true; |
916 } | 916 } |
917 } | 917 } |
918 return false; | 918 return false; |
919 } else { | 919 } else { |
920 return !obj.IsInstance(); | 920 return !obj.IsInstance(); |
921 } | 921 } |
922 } | 922 } |
923 | 923 |
924 | 924 |
| 925 static bool HandleRetainingPath(Isolate* isolate, |
| 926 Object* obj, |
| 927 intptr_t limit, |
| 928 JSONStream* js) { |
| 929 ObjectGraph graph(isolate); |
| 930 Array& path = Array::Handle(Array::New(limit * 2)); |
| 931 intptr_t length = graph.RetainingPath(obj, path); |
| 932 JSONObject jsobj(js); |
| 933 jsobj.AddProperty("type", "RetainingPath"); |
| 934 jsobj.AddProperty("id", "retaining_path"); |
| 935 jsobj.AddProperty("length", length); |
| 936 JSONArray elements(&jsobj, "elements"); |
| 937 Object& element = Object::Handle(); |
| 938 Object& parent = Object::Handle(); |
| 939 Smi& offset_from_parent = Smi::Handle(); |
| 940 Class& parent_class = Class::Handle(); |
| 941 Array& parent_field_map = Array::Handle(); |
| 942 Field& field = Field::Handle(); |
| 943 limit = Utils::Minimum(limit, length); |
| 944 for (intptr_t i = 0; i < limit; ++i) { |
| 945 JSONObject jselement(&elements); |
| 946 element = path.At(i * 2); |
| 947 jselement.AddProperty("index", i); |
| 948 jselement.AddProperty("value", element); |
| 949 // Interpret the word offset from parent as list index or instance field. |
| 950 // TODO(koda): User-friendly interpretation for map entries. |
| 951 offset_from_parent ^= path.At((i * 2) + 1); |
| 952 int parent_i = i + 1; |
| 953 if (parent_i < limit) { |
| 954 parent = path.At(parent_i * 2); |
| 955 if (parent.IsArray()) { |
| 956 intptr_t element_index = offset_from_parent.Value() - |
| 957 (Array::element_offset(0) >> kWordSizeLog2); |
| 958 jselement.AddProperty("parentListIndex", element_index); |
| 959 } else if (parent.IsInstance()) { |
| 960 parent_class ^= parent.clazz(); |
| 961 parent_field_map = parent_class.OffsetToFieldMap(); |
| 962 intptr_t offset = offset_from_parent.Value(); |
| 963 if (offset > 0 && offset < parent_field_map.Length()) { |
| 964 field ^= parent_field_map.At(offset); |
| 965 jselement.AddProperty("parentField", field); |
| 966 } |
| 967 } |
| 968 } |
| 969 } |
| 970 return true; |
| 971 } |
| 972 |
925 // Takes an Object* only because RetainingPath temporarily clears it. | 973 // Takes an Object* only because RetainingPath temporarily clears it. |
926 static bool HandleInstanceCommands(Isolate* isolate, | 974 static bool HandleInstanceCommands(Isolate* isolate, |
927 Object* obj, | 975 Object* obj, |
928 JSONStream* js, | 976 JSONStream* js, |
929 intptr_t arg_pos) { | 977 intptr_t arg_pos) { |
930 ASSERT(js->num_arguments() > arg_pos); | 978 ASSERT(js->num_arguments() > arg_pos); |
931 const char* action = js->GetArgument(arg_pos); | 979 const char* action = js->GetArgument(arg_pos); |
932 if (strcmp(action, "eval") == 0) { | 980 if (strcmp(action, "eval") == 0) { |
933 if (js->num_arguments() > (arg_pos + 1)) { | 981 if (js->num_arguments() > (arg_pos + 1)) { |
934 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n", | 982 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n", |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 const Object& result = Object::Handle(Integer::New(retained_size)); | 1021 const Object& result = Object::Handle(Integer::New(retained_size)); |
974 result.PrintJSON(js, true); | 1022 result.PrintJSON(js, true); |
975 return true; | 1023 return true; |
976 } else if (strcmp(action, "retaining_path") == 0) { | 1024 } else if (strcmp(action, "retaining_path") == 0) { |
977 intptr_t limit; | 1025 intptr_t limit; |
978 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { | 1026 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { |
979 PrintError(js, "retaining_path expects a 'limit' option\n", | 1027 PrintError(js, "retaining_path expects a 'limit' option\n", |
980 js->num_arguments()); | 1028 js->num_arguments()); |
981 return true; | 1029 return true; |
982 } | 1030 } |
983 ObjectGraph graph(isolate); | 1031 return HandleRetainingPath(isolate, obj, limit, js); |
984 Array& path = Array::Handle(Array::New(limit)); | |
985 intptr_t length = graph.RetainingPath(obj, path); | |
986 JSONObject jsobj(js); | |
987 jsobj.AddProperty("type", "RetainingPath"); | |
988 jsobj.AddProperty("id", "retaining_path"); | |
989 jsobj.AddProperty("length", length); | |
990 JSONArray elements(&jsobj, "elements"); | |
991 for (intptr_t i = 0; i < path.Length() && i < length; ++i) { | |
992 JSONObject jselement(&elements); | |
993 Object& element = Object::Handle(); | |
994 element = path.At(i); | |
995 jselement.AddProperty("index", i); | |
996 jselement.AddProperty("value", element); | |
997 } | |
998 return true; | |
999 } | 1032 } |
1000 | 1033 |
1001 PrintError(js, "unrecognized action '%s'\n", action); | 1034 PrintError(js, "unrecognized action '%s'\n", action); |
1002 return true; | 1035 return true; |
1003 } | 1036 } |
1004 | 1037 |
1005 | 1038 |
1006 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, | 1039 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, |
1007 JSONStream* js) { | 1040 JSONStream* js) { |
1008 intptr_t id; | 1041 intptr_t id; |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2268 while (current != NULL) { | 2301 while (current != NULL) { |
2269 if (strcmp(name, current->name()) == 0) { | 2302 if (strcmp(name, current->name()) == 0) { |
2270 return current; | 2303 return current; |
2271 } | 2304 } |
2272 current = current->next(); | 2305 current = current->next(); |
2273 } | 2306 } |
2274 return NULL; | 2307 return NULL; |
2275 } | 2308 } |
2276 | 2309 |
2277 } // namespace dart | 2310 } // namespace dart |
OLD | NEW |