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

Side by Side Diff: runtime/vm/service.cc

Issue 501583007: Treat null like the object it is in the Observatory and Service. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 return true; 948 return true;
949 } 949 }
950 950
951 951
952 static bool ContainsNonInstance(const Object& obj) { 952 static bool ContainsNonInstance(const Object& obj) {
953 if (obj.IsArray()) { 953 if (obj.IsArray()) {
954 const Array& array = Array::Cast(obj); 954 const Array& array = Array::Cast(obj);
955 Object& element = Object::Handle(); 955 Object& element = Object::Handle();
956 for (intptr_t i = 0; i < array.Length(); ++i) { 956 for (intptr_t i = 0; i < array.Length(); ++i) {
957 element = array.At(i); 957 element = array.At(i);
958 if (!element.IsInstance()) { 958 if (!(element.IsInstance() || element.IsNull())) {
959 return true; 959 return true;
960 } 960 }
961 } 961 }
962 return false; 962 return false;
963 } else if (obj.IsGrowableObjectArray()) { 963 } else if (obj.IsGrowableObjectArray()) {
964 const GrowableObjectArray& array = GrowableObjectArray::Cast(obj); 964 const GrowableObjectArray& array = GrowableObjectArray::Cast(obj);
965 Object& element = Object::Handle(); 965 Object& element = Object::Handle();
966 for (intptr_t i = 0; i < array.Length(); ++i) { 966 for (intptr_t i = 0; i < array.Length(); ++i) {
967 element = array.At(i); 967 element = array.At(i);
968 if (!element.IsInstance()) { 968 if (!(element.IsInstance() || element.IsNull())) {
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() || obj.IsNull());
975 } 975 }
976 } 976 }
977 977
978 978
979 static bool HandleInboundReferences(Isolate* isolate, 979 static bool HandleInboundReferences(Isolate* isolate,
980 Object* target, 980 Object* target,
981 intptr_t limit, 981 intptr_t limit,
982 JSONStream* js) { 982 JSONStream* js) {
983 ObjectGraph graph(isolate); 983 ObjectGraph graph(isolate);
984 Array& path = Array::Handle(Array::New(limit * 2)); 984 Array& path = Array::Handle(Array::New(limit * 2));
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 // We nil out the array after generating the response to prevent 1074 // We nil out the array after generating the response to prevent
1075 // reporting suprious references when looking for inbound references 1075 // reporting suprious references when looking for inbound references
1076 // after looking for a retaining path. 1076 // after looking for a retaining path.
1077 for (intptr_t i = 0; i < limit; ++i) { 1077 for (intptr_t i = 0; i < limit; ++i) {
1078 path.SetAt(i * 2, Object::null_object()); 1078 path.SetAt(i * 2, Object::null_object());
1079 } 1079 }
1080 1080
1081 return true; 1081 return true;
1082 } 1082 }
1083 1083
1084
1084 // Takes an Object* only because RetainingPath temporarily clears it. 1085 // Takes an Object* only because RetainingPath temporarily clears it.
1085 static bool HandleInstanceCommands(Isolate* isolate, 1086 static bool HandleInstanceCommands(Isolate* isolate,
1086 Object* obj, 1087 Object* obj,
1088 ObjectIdRing::LookupResult kind,
1087 JSONStream* js, 1089 JSONStream* js,
1088 intptr_t arg_pos) { 1090 intptr_t arg_pos) {
1089 ASSERT(js->num_arguments() > arg_pos); 1091 ASSERT(js->num_arguments() > arg_pos);
1092 ASSERT(kind != ObjectIdRing::kInvalid);
1090 const char* action = js->GetArgument(arg_pos); 1093 const char* action = js->GetArgument(arg_pos);
1091 if (strcmp(action, "eval") == 0) { 1094 if (strcmp(action, "eval") == 0) {
1092 if (js->num_arguments() > (arg_pos + 1)) { 1095 if (js->num_arguments() > (arg_pos + 1)) {
1093 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n", 1096 PrintError(js, "expected at most %" Pd " arguments but found %" Pd "\n",
1094 arg_pos + 1, 1097 arg_pos + 1,
1095 js->num_arguments()); 1098 js->num_arguments());
1096 return true; 1099 return true;
1097 } 1100 }
1098 if (obj->IsNull()) { 1101 if (kind == ObjectIdRing::kCollected) {
1099 PrintErrorWithKind(js, "EvalCollected", 1102 PrintErrorWithKind(js, "EvalCollected",
1100 "attempt to evaluate against collected object\n", 1103 "attempt to evaluate against collected object\n",
1101 js->num_arguments()); 1104 js->num_arguments());
1102 return true; 1105 return true;
1103 } 1106 }
1104 if (obj->raw() == Object::sentinel().raw()) { 1107 if (kind == ObjectIdRing::kExpired) {
1105 PrintErrorWithKind(js, "EvalExpired", 1108 PrintErrorWithKind(js, "EvalExpired",
1106 "attempt to evaluate against expired object\n", 1109 "attempt to evaluate against expired object\n",
1107 js->num_arguments()); 1110 js->num_arguments());
1108 return true; 1111 return true;
1109 } 1112 }
1110 if (ContainsNonInstance(*obj)) { 1113 if (ContainsNonInstance(*obj)) {
1111 PrintError(js, "attempt to evaluate against internal VM object\n"); 1114 PrintError(js, "attempt to evaluate against internal VM object\n");
1112 return true; 1115 return true;
1113 } 1116 }
1114 const char* expr = js->LookupOption("expr"); 1117 const char* expr = js->LookupOption("expr");
1115 if (expr == NULL) { 1118 if (expr == NULL) {
1116 PrintError(js, "eval expects an 'expr' option\n", 1119 PrintError(js, "eval expects an 'expr' option\n",
1117 js->num_arguments()); 1120 js->num_arguments());
1118 return true; 1121 return true;
1119 } 1122 }
1120 const String& expr_str = String::Handle(isolate, String::New(expr)); 1123 const String& expr_str = String::Handle(isolate, String::New(expr));
1121 ASSERT(obj->IsInstance()); 1124 ASSERT(obj->IsInstance());
1122 const Instance& instance = Instance::Cast(*obj); 1125 const Instance& instance = Instance::Cast(*obj);
1123 const Object& result = 1126 const Object& result =
1124 Object::Handle(instance.Evaluate(expr_str, 1127 Object::Handle(instance.Evaluate(expr_str,
1125 Array::empty_array(), 1128 Array::empty_array(),
1126 Array::empty_array())); 1129 Array::empty_array()));
1127 result.PrintJSON(js, true); 1130 result.PrintJSON(js, true);
1128 return true; 1131 return true;
1129 } else if (strcmp(action, "retained") == 0) { 1132 } else if (strcmp(action, "retained") == 0) {
1133 if (kind == ObjectIdRing::kCollected) {
1134 PrintErrorWithKind(
1135 js, "RetainedCollected",
1136 "attempt to calculate size retained by a collected object\n",
1137 js->num_arguments());
1138 return true;
1139 }
1140 if (kind == ObjectIdRing::kExpired) {
1141 PrintErrorWithKind(
1142 js, "RetainedExpired",
1143 "attempt to calculate size retained by an expired object\n",
1144 js->num_arguments());
1145 return true;
1146 }
1130 ObjectGraph graph(isolate); 1147 ObjectGraph graph(isolate);
1131 intptr_t retained_size = graph.SizeRetainedByInstance(*obj); 1148 intptr_t retained_size = graph.SizeRetainedByInstance(*obj);
1132 const Object& result = Object::Handle(Integer::New(retained_size)); 1149 const Object& result = Object::Handle(Integer::New(retained_size));
1133 result.PrintJSON(js, true); 1150 result.PrintJSON(js, true);
1134 return true; 1151 return true;
1135 } else if (strcmp(action, "retaining_path") == 0) { 1152 } else if (strcmp(action, "retaining_path") == 0) {
1153 if (kind == ObjectIdRing::kCollected) {
1154 PrintErrorWithKind(
1155 js, "RetainingPathCollected",
1156 "attempt to find a retaining path for a collected object\n",
1157 js->num_arguments());
1158 return true;
1159 }
1160 if (kind == ObjectIdRing::kExpired) {
1161 PrintErrorWithKind(
1162 js, "RetainingPathExpired",
1163 "attempt to find a retaining path for an expired object\n",
1164 js->num_arguments());
1165 return true;
1166 }
1136 intptr_t limit; 1167 intptr_t limit;
1137 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { 1168 if (!GetIntegerId(js->LookupOption("limit"), &limit)) {
1138 PrintError(js, "retaining_path expects a 'limit' option\n", 1169 PrintError(js, "retaining_path expects a 'limit' option\n",
1139 js->num_arguments()); 1170 js->num_arguments());
1140 return true; 1171 return true;
1141 } 1172 }
1142 return HandleRetainingPath(isolate, obj, limit, js); 1173 return HandleRetainingPath(isolate, obj, limit, js);
1143 } else if (strcmp(action, "inbound_references") == 0) { 1174 } else if (strcmp(action, "inbound_references") == 0) {
1175 if (kind == ObjectIdRing::kCollected) {
1176 PrintErrorWithKind(
1177 js, "InboundReferencesCollected",
1178 "attempt to find inbound references for a collected object\n",
1179 js->num_arguments());
1180 return true;
1181 }
1182 if (kind == ObjectIdRing::kExpired) {
1183 PrintErrorWithKind(
1184 js, "InboundReferencesExpired",
1185 "attempt to find inbound references for an expired object\n",
1186 js->num_arguments());
1187 return true;
1188 }
1144 intptr_t limit; 1189 intptr_t limit;
1145 if (!GetIntegerId(js->LookupOption("limit"), &limit)) { 1190 if (!GetIntegerId(js->LookupOption("limit"), &limit)) {
1146 PrintError(js, "inbound_references expects a 'limit' option\n", 1191 PrintError(js, "inbound_references expects a 'limit' option\n",
1147 js->num_arguments()); 1192 js->num_arguments());
1148 return true; 1193 return true;
1149 } 1194 }
1150 return HandleInboundReferences(isolate, obj, limit, js); 1195 return HandleInboundReferences(isolate, obj, limit, js);
1151 } 1196 }
1152 1197
1153 PrintError(js, "unrecognized action '%s'\n", action); 1198 PrintError(js, "unrecognized action '%s'\n", action);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 Type& type = Type::Handle(); 1374 Type& type = Type::Handle();
1330 type ^= cls.CanonicalTypeFromIndex(id); 1375 type ^= cls.CanonicalTypeFromIndex(id);
1331 if (type.IsNull()) { 1376 if (type.IsNull()) {
1332 PrintError(js, "Canonical type %" Pd " not found", id); 1377 PrintError(js, "Canonical type %" Pd " not found", id);
1333 return true; 1378 return true;
1334 } 1379 }
1335 if (js->num_arguments() == 4) { 1380 if (js->num_arguments() == 4) {
1336 type.PrintJSON(js, false); 1381 type.PrintJSON(js, false);
1337 return true; 1382 return true;
1338 } 1383 }
1339 return HandleInstanceCommands(isolate, &type, js, 4); 1384 return HandleInstanceCommands(isolate, &type, ObjectIdRing::kValid, js, 4);
1340 } 1385 }
1341 1386
1342 1387
1343 static bool HandleClassesRetained(Isolate* isolate, const Class& cls, 1388 static bool HandleClassesRetained(Isolate* isolate, const Class& cls,
1344 JSONStream* js) { 1389 JSONStream* js) {
1345 if (js->num_arguments() != 3) { 1390 if (js->num_arguments() != 3) {
1346 PrintError(js, "Command too long"); 1391 PrintError(js, "Command too long");
1347 return true; 1392 return true;
1348 } 1393 }
1349 ObjectGraph graph(isolate); 1394 ObjectGraph graph(isolate);
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 const char* preview) { 1678 const char* preview) {
1634 JSONObject jsobj(js); 1679 JSONObject jsobj(js);
1635 jsobj.AddProperty("type", "Null"); 1680 jsobj.AddProperty("type", "Null");
1636 jsobj.AddProperty("id", id); 1681 jsobj.AddProperty("id", id);
1637 jsobj.AddProperty("valueAsString", preview); 1682 jsobj.AddProperty("valueAsString", preview);
1638 } 1683 }
1639 1684
1640 1685
1641 static RawObject* LookupObjectId(Isolate* isolate, 1686 static RawObject* LookupObjectId(Isolate* isolate,
1642 const char* arg, 1687 const char* arg,
1643 bool* error) { 1688 ObjectIdRing::LookupResult* kind) {
1644 *error = false; 1689 *kind = ObjectIdRing::kValid;
1645 if (strncmp(arg, "int-", 4) == 0) { 1690 if (strncmp(arg, "int-", 4) == 0) {
1646 arg += 4; 1691 arg += 4;
1647 int64_t value = 0; 1692 int64_t value = 0;
1648 if (!OS::StringToInt64(arg, &value) || 1693 if (!OS::StringToInt64(arg, &value) ||
1649 !Smi::IsValid(value)) { 1694 !Smi::IsValid(value)) {
1650 *error = true; 1695 *kind = ObjectIdRing::kInvalid;
1651 return Object::null(); 1696 return Object::null();
1652 } 1697 }
1653 const Integer& obj = 1698 const Integer& obj =
1654 Integer::Handle(isolate, Smi::New(static_cast<intptr_t>(value))); 1699 Integer::Handle(isolate, Smi::New(static_cast<intptr_t>(value)));
1655 return obj.raw(); 1700 return obj.raw();
1656
1657 } else if (strcmp(arg, "bool-true") == 0) { 1701 } else if (strcmp(arg, "bool-true") == 0) {
1658 return Bool::True().raw(); 1702 return Bool::True().raw();
1659
1660 } else if (strcmp(arg, "bool-false") == 0) { 1703 } else if (strcmp(arg, "bool-false") == 0) {
1661 return Bool::False().raw(); 1704 return Bool::False().raw();
1705 } else if (strcmp(arg, "null") == 0) {
1706 return Object::null();
1707 } else if (strcmp(arg, "not-initialized") == 0) {
1708 return Object::sentinel().raw();
1709 } else if (strcmp(arg, "being-initialized") == 0) {
1710 return Object::transition_sentinel().raw();
1662 } 1711 }
1663 1712
1664 ObjectIdRing* ring = isolate->object_id_ring(); 1713 ObjectIdRing* ring = isolate->object_id_ring();
1665 ASSERT(ring != NULL); 1714 ASSERT(ring != NULL);
1666 intptr_t id = -1; 1715 intptr_t id = -1;
1667 if (!GetIntegerId(arg, &id)) { 1716 if (!GetIntegerId(arg, &id)) {
1668 *error = true; 1717 *kind = ObjectIdRing::kInvalid;
1669 return Instance::null(); 1718 return Object::null();
1670 } 1719 }
1671 return ring->GetObjectForId(id); 1720 return ring->GetObjectForId(id, kind);
1672 } 1721 }
1673 1722
1674 1723
1675 static RawClass* GetMetricsClass(Isolate* isolate) { 1724 static RawClass* GetMetricsClass(Isolate* isolate) {
1676 const Library& prof_lib = 1725 const Library& prof_lib =
1677 Library::Handle(isolate, Library::ProfilerLibrary()); 1726 Library::Handle(isolate, Library::ProfilerLibrary());
1678 ASSERT(!prof_lib.IsNull()); 1727 ASSERT(!prof_lib.IsNull());
1679 const String& metrics_cls_name = 1728 const String& metrics_cls_name =
1680 String::Handle(isolate, String::New("Metrics")); 1729 String::Handle(isolate, String::New("Metrics"));
1681 ASSERT(!metrics_cls_name.IsNull()); 1730 ASSERT(!metrics_cls_name.IsNull());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 1843
1795 static bool HandleObjects(Isolate* isolate, JSONStream* js) { 1844 static bool HandleObjects(Isolate* isolate, JSONStream* js) {
1796 REQUIRE_COLLECTION_ID("objects"); 1845 REQUIRE_COLLECTION_ID("objects");
1797 if (js->num_arguments() < 2) { 1846 if (js->num_arguments() < 2) {
1798 PrintError(js, "expected at least 2 arguments but found %" Pd "\n", 1847 PrintError(js, "expected at least 2 arguments but found %" Pd "\n",
1799 js->num_arguments()); 1848 js->num_arguments());
1800 return true; 1849 return true;
1801 } 1850 }
1802 const char* arg = js->GetArgument(1); 1851 const char* arg = js->GetArgument(1);
1803 1852
1804 // Handle special objects first. 1853 // Handle special non-objects first.
1805 if (strcmp(arg, "null") == 0) { 1854 if (strcmp(arg, "optimized-out") == 0) {
1806 if (js->num_arguments() > 2) { 1855 if (js->num_arguments() > 2) {
1807 PrintError(js, "expected at most 2 arguments but found %" Pd "\n", 1856 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1808 js->num_arguments()); 1857 js->num_arguments());
1809 } else {
1810 Instance::null_instance().PrintJSON(js, false);
1811 }
1812 return true;
1813
1814 } else if (strcmp(arg, "not-initialized") == 0) {
1815 if (js->num_arguments() > 2) {
1816 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1817 js->num_arguments());
1818 } else {
1819 Object::sentinel().PrintJSON(js, false);
1820 }
1821 return true;
1822
1823 } else if (strcmp(arg, "being-initialized") == 0) {
1824 if (js->num_arguments() > 2) {
1825 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1826 js->num_arguments());
1827 } else {
1828 Object::transition_sentinel().PrintJSON(js, false);
1829 }
1830 return true;
1831
1832 } else if (strcmp(arg, "optimized-out") == 0) {
1833 if (js->num_arguments() > 2) {
1834 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1835 js->num_arguments());
1836 } else { 1858 } else {
1837 Symbols::OptimizedOut().PrintJSON(js, false); 1859 Symbols::OptimizedOut().PrintJSON(js, false);
1838 } 1860 }
1839 return true; 1861 return true;
1840 1862
1841 } else if (strcmp(arg, "collected") == 0) { 1863 } else if (strcmp(arg, "collected") == 0) {
1842 if (js->num_arguments() > 2) { 1864 if (js->num_arguments() > 2) {
1843 PrintError(js, "expected at most 2 arguments but found %" Pd "\n", 1865 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1844 js->num_arguments()); 1866 js->num_arguments());
1845 } else { 1867 } else {
1846 PrintPseudoNull(js, "objects/collected", "<collected>"); 1868 PrintPseudoNull(js, "objects/collected", "<collected>");
1847 } 1869 }
1848 return true; 1870 return true;
1849 1871
1850 } else if (strcmp(arg, "expired") == 0) { 1872 } else if (strcmp(arg, "expired") == 0) {
1851 if (js->num_arguments() > 2) { 1873 if (js->num_arguments() > 2) {
1852 PrintError(js, "expected at most 2 arguments but found %" Pd "\n", 1874 PrintError(js, "expected at most 2 arguments but found %" Pd "\n",
1853 js->num_arguments()); 1875 js->num_arguments());
1854 } else { 1876 } else {
1855 PrintPseudoNull(js, "objects/expired", "<expired>"); 1877 PrintPseudoNull(js, "objects/expired", "<expired>");
1856 } 1878 }
1857 return true; 1879 return true;
1858 } 1880 }
1859 1881
1860 // Lookup the object. 1882 // Lookup the object.
1861 Object& obj = Object::Handle(isolate); 1883 Object& obj = Object::Handle(isolate);
1862 bool error = false; 1884 ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
1863 obj = LookupObjectId(isolate, arg, &error); 1885 obj = LookupObjectId(isolate, arg, &kind);
1864 if (error) { 1886 if (kind == ObjectIdRing::kInvalid) {
1865 PrintError(js, "unrecognized object id '%s'", arg); 1887 PrintError(js, "unrecognized object id '%s'", arg);
1866 return true; 1888 return true;
1867 } 1889 }
1868 if (js->num_arguments() == 2) { 1890 if (js->num_arguments() == 2) {
1869 // Print. 1891 // Print.
1870 if (obj.IsNull()) { 1892 if (kind == ObjectIdRing::kCollected) {
1871 // The object has been collected by the gc. 1893 // The object has been collected by the gc.
1872 PrintPseudoNull(js, "objects/collected", "<collected>"); 1894 PrintPseudoNull(js, "objects/collected", "<collected>");
1873 return true; 1895 return true;
1874 } else if (obj.raw() == Object::sentinel().raw()) { 1896 } else if (kind == ObjectIdRing::kExpired) {
1875 // The object id has expired. 1897 // The object id has expired.
1876 PrintPseudoNull(js, "objects/expired", "<expired>"); 1898 PrintPseudoNull(js, "objects/expired", "<expired>");
1877 return true; 1899 return true;
1878 } 1900 }
1879 obj.PrintJSON(js, false); 1901 obj.PrintJSON(js, false);
1880 return true; 1902 return true;
1881 } 1903 }
1882 return HandleInstanceCommands(isolate, &obj, js, 2); 1904 return HandleInstanceCommands(isolate, &obj, kind, js, 2);
1883 } 1905 }
1884 1906
1885 1907
1886 static bool HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) { 1908 static bool HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
1887 JSONObject jsobj(js); 1909 JSONObject jsobj(js);
1888 jsobj.AddProperty("type", "ScriptList"); 1910 jsobj.AddProperty("type", "ScriptList");
1889 jsobj.AddProperty("id", "scripts"); 1911 jsobj.AddProperty("id", "scripts");
1890 JSONArray members(&jsobj, "members"); 1912 JSONArray members(&jsobj, "members");
1891 const GrowableObjectArray& libs = 1913 const GrowableObjectArray& libs =
1892 GrowableObjectArray::Handle(isolate->object_store()->libraries()); 1914 GrowableObjectArray::Handle(isolate->object_store()->libraries());
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 while (current != NULL) { 2710 while (current != NULL) {
2689 if (strcmp(name, current->name()) == 0) { 2711 if (strcmp(name, current->name()) == 0) {
2690 return current; 2712 return current;
2691 } 2713 }
2692 current = current->next(); 2714 current = current->next();
2693 } 2715 }
2694 return NULL; 2716 return NULL;
2695 } 2717 }
2696 2718
2697 } // namespace dart 2719 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698