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 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 return true; | 969 return true; |
970 } | 970 } |
971 } | 971 } |
972 return false; | 972 return false; |
973 } else { | 973 } else { |
974 return !obj.IsInstance(); | 974 return !obj.IsInstance(); |
975 } | 975 } |
976 } | 976 } |
977 | 977 |
978 | 978 |
| 979 static bool HandleInboundReferences(Isolate* isolate, |
| 980 Object* target, |
| 981 intptr_t limit, |
| 982 JSONStream* js) { |
| 983 ObjectGraph graph(isolate); |
| 984 Array& path = Array::Handle(Array::New(limit * 2)); |
| 985 intptr_t length = graph.InboundReferences(target, path); |
| 986 JSONObject jsobj(js); |
| 987 jsobj.AddProperty("type", "InboundReferences"); |
| 988 jsobj.AddProperty("id", "inbound_references"); |
| 989 { |
| 990 JSONArray elements(&jsobj, "references"); |
| 991 Object& source = Object::Handle(); |
| 992 Smi& slot_offset = Smi::Handle(); |
| 993 Class& source_class = Class::Handle(); |
| 994 Field& field = Field::Handle(); |
| 995 Array& parent_field_map = Array::Handle(); |
| 996 limit = Utils::Minimum(limit, length); |
| 997 for (intptr_t i = 0; i < limit; ++i) { |
| 998 JSONObject jselement(&elements); |
| 999 source = path.At(i * 2); |
| 1000 slot_offset ^= path.At((i * 2) + 1); |
| 1001 |
| 1002 jselement.AddProperty("source", source); |
| 1003 jselement.AddProperty("slot", "<unknown>"); |
| 1004 if (source.IsArray()) { |
| 1005 intptr_t element_index = slot_offset.Value() - |
| 1006 (Array::element_offset(0) >> kWordSizeLog2); |
| 1007 jselement.AddProperty("slot", element_index); |
| 1008 } else if (source.IsInstance()) { |
| 1009 source_class ^= source.clazz(); |
| 1010 parent_field_map = source_class.OffsetToFieldMap(); |
| 1011 intptr_t offset = slot_offset.Value(); |
| 1012 if (offset > 0 && offset < parent_field_map.Length()) { |
| 1013 field ^= parent_field_map.At(offset); |
| 1014 jselement.AddProperty("slot", field); |
| 1015 } |
| 1016 } |
| 1017 |
| 1018 // We nil out the array after generating the response to prevent |
| 1019 // reporting suprious references when repeatedly looking for the |
| 1020 // references to an object. |
| 1021 path.SetAt(i * 2, Object::null_object()); |
| 1022 } |
| 1023 } |
| 1024 return true; |
| 1025 } |
| 1026 |
| 1027 |
979 static bool HandleRetainingPath(Isolate* isolate, | 1028 static bool HandleRetainingPath(Isolate* isolate, |
980 Object* obj, | 1029 Object* obj, |
981 intptr_t limit, | 1030 intptr_t limit, |
982 JSONStream* js) { | 1031 JSONStream* js) { |
983 ObjectGraph graph(isolate); | 1032 ObjectGraph graph(isolate); |
984 Array& path = Array::Handle(Array::New(limit * 2)); | 1033 Array& path = Array::Handle(Array::New(limit * 2)); |
985 intptr_t length = graph.RetainingPath(obj, path); | 1034 intptr_t length = graph.RetainingPath(obj, path); |
986 JSONObject jsobj(js); | 1035 JSONObject jsobj(js); |
987 jsobj.AddProperty("type", "RetainingPath"); | 1036 jsobj.AddProperty("type", "RetainingPath"); |
988 jsobj.AddProperty("id", "retaining_path"); | 1037 jsobj.AddProperty("id", "retaining_path"); |
(...skipping 25 matching lines...) Expand all Loading... |
1014 parent_class ^= parent.clazz(); | 1063 parent_class ^= parent.clazz(); |
1015 parent_field_map = parent_class.OffsetToFieldMap(); | 1064 parent_field_map = parent_class.OffsetToFieldMap(); |
1016 intptr_t offset = offset_from_parent.Value(); | 1065 intptr_t offset = offset_from_parent.Value(); |
1017 if (offset > 0 && offset < parent_field_map.Length()) { | 1066 if (offset > 0 && offset < parent_field_map.Length()) { |
1018 field ^= parent_field_map.At(offset); | 1067 field ^= parent_field_map.At(offset); |
1019 jselement.AddProperty("parentField", field); | 1068 jselement.AddProperty("parentField", field); |
1020 } | 1069 } |
1021 } | 1070 } |
1022 } | 1071 } |
1023 } | 1072 } |
| 1073 |
| 1074 // We nil out the array after generating the response to prevent |
| 1075 // reporting suprious references when looking for inbound references |
| 1076 // after looking for a retaining path. |
| 1077 for (intptr_t i = 0; i < limit; ++i) { |
| 1078 path.SetAt(i * 2, Object::null_object()); |
| 1079 } |
| 1080 |
1024 return true; | 1081 return true; |
1025 } | 1082 } |
1026 | 1083 |
1027 // Takes an Object* only because RetainingPath temporarily clears it. | 1084 // Takes an Object* only because RetainingPath temporarily clears it. |
1028 static bool HandleInstanceCommands(Isolate* isolate, | 1085 static bool HandleInstanceCommands(Isolate* isolate, |
1029 Object* obj, | 1086 Object* obj, |
1030 JSONStream* js, | 1087 JSONStream* js, |
1031 intptr_t arg_pos) { | 1088 intptr_t arg_pos) { |
1032 ASSERT(js->num_arguments() > arg_pos); | 1089 ASSERT(js->num_arguments() > arg_pos); |
1033 const char* action = js->GetArgument(arg_pos); | 1090 const char* action = js->GetArgument(arg_pos); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 result.PrintJSON(js, true); | 1133 result.PrintJSON(js, true); |
1077 return true; | 1134 return true; |
1078 } else if (strcmp(action, "retaining_path") == 0) { | 1135 } else if (strcmp(action, "retaining_path") == 0) { |
1079 intptr_t limit; | 1136 intptr_t limit; |
1080 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { | 1137 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { |
1081 PrintError(js, "retaining_path expects a 'limit' option\n", | 1138 PrintError(js, "retaining_path expects a 'limit' option\n", |
1082 js->num_arguments()); | 1139 js->num_arguments()); |
1083 return true; | 1140 return true; |
1084 } | 1141 } |
1085 return HandleRetainingPath(isolate, obj, limit, js); | 1142 return HandleRetainingPath(isolate, obj, limit, js); |
| 1143 } else if (strcmp(action, "inbound_references") == 0) { |
| 1144 intptr_t limit; |
| 1145 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { |
| 1146 PrintError(js, "inbound_references expects a 'limit' option\n", |
| 1147 js->num_arguments()); |
| 1148 return true; |
| 1149 } |
| 1150 return HandleInboundReferences(isolate, obj, limit, js); |
1086 } | 1151 } |
1087 | 1152 |
1088 PrintError(js, "unrecognized action '%s'\n", action); | 1153 PrintError(js, "unrecognized action '%s'\n", action); |
1089 return true; | 1154 return true; |
1090 } | 1155 } |
1091 | 1156 |
1092 | 1157 |
1093 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, | 1158 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, |
1094 JSONStream* js) { | 1159 JSONStream* js) { |
1095 intptr_t id; | 1160 intptr_t id; |
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 while (current != NULL) { | 2688 while (current != NULL) { |
2624 if (strcmp(name, current->name()) == 0) { | 2689 if (strcmp(name, current->name()) == 0) { |
2625 return current; | 2690 return current; |
2626 } | 2691 } |
2627 current = current->next(); | 2692 current = current->next(); |
2628 } | 2693 } |
2629 return NULL; | 2694 return NULL; |
2630 } | 2695 } |
2631 | 2696 |
2632 } // namespace dart | 2697 } // namespace dart |
OLD | NEW |