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 |