Chromium Code Reviews| 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 | 8 |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/coverage.h" | 10 #include "vm/coverage.h" |
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 r = strtoul(s, &end_ptr, base); | 709 r = strtoul(s, &end_ptr, base); |
| 710 if (end_ptr == s) { | 710 if (end_ptr == s) { |
| 711 // String was not advanced at all, cannot be valid. | 711 // String was not advanced at all, cannot be valid. |
| 712 return false; | 712 return false; |
| 713 } | 713 } |
| 714 *id = r; | 714 *id = r; |
| 715 return true; | 715 return true; |
| 716 } | 716 } |
| 717 | 717 |
| 718 | 718 |
| 719 static bool GetInteger64Id(const char* s, int64_t* id, int base = 10) { | |
| 720 if ((s == NULL) || (*s == '\0')) { | |
| 721 // Empty string. | |
| 722 return false; | |
| 723 } | |
| 724 if (id == NULL) { | |
| 725 // No id pointer. | |
| 726 return false; | |
| 727 } | |
| 728 int64_t r = 0; | |
| 729 char* end_ptr = NULL; | |
| 730 r = strtoll(s, &end_ptr, base); | |
| 731 if (end_ptr == s) { | |
| 732 // String was not advanced at all, cannot be valid. | |
| 733 return false; | |
| 734 } | |
| 735 *id = r; | |
| 736 return true; | |
| 737 } | |
| 738 | |
| 739 // Scans the string until the '-' character. Returns pointer to string | |
| 740 // at '-' character. Returns NULL if not found. | |
| 741 const char* ScanUntilDash(const char* s) { | |
| 742 if ((s == NULL) || (*s == '\0')) { | |
| 743 // Empty string. | |
| 744 return NULL; | |
| 745 } | |
| 746 while (*s != '\0') { | |
| 747 if (*s == '-') { | |
| 748 return s; | |
| 749 } | |
| 750 s++; | |
| 751 } | |
| 752 return NULL; | |
| 753 } | |
| 754 | |
| 755 | |
| 719 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, | 756 static bool HandleClassesClosures(Isolate* isolate, const Class& cls, |
| 720 JSONStream* js) { | 757 JSONStream* js) { |
| 721 intptr_t id; | 758 intptr_t id; |
| 722 if (js->num_arguments() > 4) { | 759 if (js->num_arguments() > 4) { |
| 723 PrintError(js, "Command too long"); | 760 PrintError(js, "Command too long"); |
| 724 return true; | 761 return true; |
| 725 } | 762 } |
| 726 if (!GetIntegerId(js->GetArgument(3), &id)) { | 763 if (!GetIntegerId(js->GetArgument(3), &id)) { |
| 727 PrintError(js, "Must specify collection object id: closures/id"); | 764 PrintError(js, "Must specify collection object id: closures/id"); |
| 728 return true; | 765 return true; |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1183 // TODO(turnidge): Consider adding/using Object::null_code() for | 1220 // TODO(turnidge): Consider adding/using Object::null_code() for |
| 1184 // consistent "type". | 1221 // consistent "type". |
| 1185 Object::null_object().PrintToJSONStream(js, false); | 1222 Object::null_object().PrintToJSONStream(js, false); |
| 1186 return true; | 1223 return true; |
| 1187 } | 1224 } |
| 1188 | 1225 |
| 1189 | 1226 |
| 1190 static bool HandleCode(Isolate* isolate, JSONStream* js) { | 1227 static bool HandleCode(Isolate* isolate, JSONStream* js) { |
| 1191 REQUIRE_COLLECTION_ID("code"); | 1228 REQUIRE_COLLECTION_ID("code"); |
| 1192 uintptr_t pc; | 1229 uintptr_t pc; |
| 1193 if (js->num_arguments() > 3) { | 1230 if (js->num_arguments() > 2) { |
| 1194 PrintError(js, "Command too long"); | 1231 PrintError(js, "Command too long"); |
| 1195 return true; | 1232 return true; |
| 1196 } | 1233 } |
| 1197 if (js->num_arguments() == 3) { | 1234 ASSERT(js->num_arguments() == 2); |
| 1198 const char* command = js->GetArgument(1); | 1235 static const char* kCollectedPrefix = "collected-"; |
| 1199 if ((strcmp("collected", command) == 0) || | 1236 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); |
| 1200 (strcmp("native", command) == 0)) { | 1237 static const char* kNativePrefix = "native-"; |
| 1201 if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) { | 1238 static intptr_t kNativePrefixLen = strlen(kNativePrefix); |
| 1202 PrintError(js, "Must specify code address: code/%s/c0deadd0.", command); | 1239 static const char* kReusedPrefix = "reused-"; |
| 1203 return true; | 1240 static intptr_t kReusedPrefixLen = strlen(kReusedPrefix); |
| 1204 } | 1241 const char* command = js->GetArgument(1); |
| 1205 return HandleNullCode(pc, js); | 1242 if (strncmp(kCollectedPrefix, command, kCollectedPrefixLen) == 0) { |
| 1206 } else { | 1243 if (!GetUnsignedIntegerId(&command[kCollectedPrefixLen], &pc, 16)) { |
| 1207 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); | 1244 PrintError(js, "Must specify code address: code/%sc0deadd0.", |
| 1245 kCollectedPrefix); | |
| 1208 return true; | 1246 return true; |
| 1209 } | 1247 } |
| 1248 return HandleNullCode(pc, js); | |
| 1210 } | 1249 } |
| 1211 ASSERT(js->num_arguments() == 2); | 1250 if (strncmp(kNativePrefix, command, kNativePrefixLen) == 0) { |
| 1212 if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) { | 1251 if (!GetUnsignedIntegerId(&command[kNativePrefixLen], &pc, 16)) { |
| 1213 PrintError(js, "Must specify code address: code/c0deadd0."); | 1252 PrintError(js, "Must specify code address: code/%sc0deadd0.", |
| 1253 kNativePrefix); | |
| 1254 return true; | |
| 1255 } | |
| 1256 // TODO(johnmccutchan): Support native Code. | |
| 1257 return HandleNullCode(pc, js); | |
| 1258 } | |
| 1259 if (strncmp(kReusedPrefix, command, kReusedPrefixLen) == 0) { | |
| 1260 if (!GetUnsignedIntegerId(&command[kReusedPrefixLen], &pc, 16)) { | |
| 1261 PrintError(js, "Must specify code address: code/%sc0deadd0.", | |
| 1262 kReusedPrefix); | |
| 1263 return true; | |
| 1264 } | |
| 1265 return HandleNullCode(pc, js); | |
| 1266 } | |
| 1267 int64_t timestamp = 0; | |
| 1268 // Extract the timestamp. | |
| 1269 if (!GetInteger64Id(command, ×tamp, 16) || (timestamp < 0)) { | |
| 1270 PrintError(js, "Malformed code id: %s", command); | |
| 1214 return true; | 1271 return true; |
| 1215 } | 1272 } |
| 1216 Code& code = Code::Handle(); | 1273 const char* sub_command = ScanUntilDash(command); |
| 1217 code ^= Code::LookupCode(pc); | 1274 if (sub_command == NULL) { |
| 1275 PrintError(js, "Malformed code id: %s", command); | |
| 1276 return true; | |
| 1277 } | |
| 1278 // Skip the dash. | |
| 1279 sub_command++; | |
| 1280 // Extract the PC. | |
| 1281 if (!GetUnsignedIntegerId(sub_command, &pc, 16)) { | |
| 1282 PrintError(js, "Malformed code id: %s", command); | |
| 1283 return true; | |
| 1284 } | |
|
turnidge
2014/03/13 18:09:09
Might be good to make a combo function which parse
Cutch
2014/03/13 20:52:26
Done.
| |
| 1285 Code& code = Code::Handle(Code::FindCode(pc, timestamp)); | |
| 1218 if (!code.IsNull()) { | 1286 if (!code.IsNull()) { |
| 1219 code.PrintToJSONStream(js, false); | 1287 code.PrintToJSONStream(js, false); |
| 1220 return true; | 1288 return true; |
| 1221 } | 1289 } |
| 1222 code ^= Code::LookupCodeInVmIsolate(pc); | 1290 PrintError(js, "Could not find code with id: %s", command); |
| 1223 if (!code.IsNull()) { | |
| 1224 code.PrintToJSONStream(js, false); | |
| 1225 return true; | |
| 1226 } | |
| 1227 PrintError(js, "Could not find code at %" Px "", pc); | |
| 1228 return true; | 1291 return true; |
| 1229 } | 1292 } |
| 1230 | 1293 |
| 1231 | 1294 |
| 1232 static bool HandleProfile(Isolate* isolate, JSONStream* js) { | 1295 static bool HandleProfile(Isolate* isolate, JSONStream* js) { |
| 1233 // A full profile includes disassembly of all Dart code objects. | 1296 // A full profile includes disassembly of all Dart code objects. |
| 1234 // TODO(johnmccutchan): Add sub command to trigger full code dump. | 1297 // TODO(johnmccutchan): Add sub command to trigger full code dump. |
| 1235 bool full_profile = false; | 1298 bool full_profile = false; |
| 1236 Profiler::PrintToJSONStream(isolate, js, full_profile); | 1299 Profiler::PrintToJSONStream(isolate, js, full_profile); |
| 1237 return true; | 1300 return true; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1505 while (current != NULL) { | 1568 while (current != NULL) { |
| 1506 if (strcmp(name, current->name()) == 0) { | 1569 if (strcmp(name, current->name()) == 0) { |
| 1507 return current; | 1570 return current; |
| 1508 } | 1571 } |
| 1509 current = current->next(); | 1572 current = current->next(); |
| 1510 } | 1573 } |
| 1511 return NULL; | 1574 return NULL; |
| 1512 } | 1575 } |
| 1513 | 1576 |
| 1514 } // namespace dart | 1577 } // namespace dart |
| OLD | NEW |