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

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

Powered by Google App Engine
This is Rietveld 408576698