| Index: runtime/vm/service.cc
|
| diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
|
| index bc77d04549fc2ab599b4a720b1b6748964416372..1903e4ba01f2e05987a094fc62aabccc950988f2 100644
|
| --- a/runtime/vm/service.cc
|
| +++ b/runtime/vm/service.cc
|
| @@ -716,6 +716,70 @@ static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) {
|
| }
|
|
|
|
|
| +static bool GetInteger64Id(const char* s, int64_t* id, int base = 10) {
|
| + if ((s == NULL) || (*s == '\0')) {
|
| + // Empty string.
|
| + return false;
|
| + }
|
| + if (id == NULL) {
|
| + // No id pointer.
|
| + return false;
|
| + }
|
| + int64_t r = 0;
|
| + char* end_ptr = NULL;
|
| + r = strtoll(s, &end_ptr, base);
|
| + if (end_ptr == s) {
|
| + // String was not advanced at all, cannot be valid.
|
| + return false;
|
| + }
|
| + *id = r;
|
| + return true;
|
| +}
|
| +
|
| +// Scans the string until the '-' character. Returns pointer to string
|
| +// at '-' character. Returns NULL if not found.
|
| +const char* ScanUntilDash(const char* s) {
|
| + if ((s == NULL) || (*s == '\0')) {
|
| + // Empty string.
|
| + return NULL;
|
| + }
|
| + while (*s != '\0') {
|
| + if (*s == '-') {
|
| + return s;
|
| + }
|
| + s++;
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +static bool GetCodeId(const char* s, int64_t* timestamp, uword* address) {
|
| + if ((s == NULL) || (*s == '\0')) {
|
| + // Empty string.
|
| + return false;
|
| + }
|
| + if ((timestamp == NULL) || (address == NULL)) {
|
| + // Bad arguments.
|
| + return false;
|
| + }
|
| + // Extract the timestamp.
|
| + if (!GetInteger64Id(s, timestamp, 16) || (*timestamp < 0)) {
|
| + return false;
|
| + }
|
| + s = ScanUntilDash(s);
|
| + if (s == NULL) {
|
| + return false;
|
| + }
|
| + // Skip the dash.
|
| + s++;
|
| + // Extract the PC.
|
| + if (!GetUnsignedIntegerId(s, address, 16)) {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +
|
| static bool HandleClassesClosures(Isolate* isolate, const Class& cls,
|
| JSONStream* js) {
|
| intptr_t id;
|
| @@ -1189,42 +1253,55 @@ static bool HandleNullCode(uintptr_t pc, JSONStream* js) {
|
|
|
| static bool HandleCode(Isolate* isolate, JSONStream* js) {
|
| REQUIRE_COLLECTION_ID("code");
|
| - uintptr_t pc;
|
| - if (js->num_arguments() > 3) {
|
| + uword pc;
|
| + if (js->num_arguments() > 2) {
|
| PrintError(js, "Command too long");
|
| return true;
|
| }
|
| - if (js->num_arguments() == 3) {
|
| - const char* command = js->GetArgument(1);
|
| - if ((strcmp("collected", command) == 0) ||
|
| - (strcmp("native", command) == 0)) {
|
| - if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
|
| - PrintError(js, "Must specify code address: code/%s/c0deadd0.", command);
|
| - return true;
|
| - }
|
| - return HandleNullCode(pc, js);
|
| - } else {
|
| - PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1));
|
| + ASSERT(js->num_arguments() == 2);
|
| + static const char* kCollectedPrefix = "collected-";
|
| + static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix);
|
| + static const char* kNativePrefix = "native-";
|
| + static intptr_t kNativePrefixLen = strlen(kNativePrefix);
|
| + static const char* kReusedPrefix = "reused-";
|
| + static intptr_t kReusedPrefixLen = strlen(kReusedPrefix);
|
| + const char* command = js->GetArgument(1);
|
| + if (strncmp(kCollectedPrefix, command, kCollectedPrefixLen) == 0) {
|
| + if (!GetUnsignedIntegerId(&command[kCollectedPrefixLen], &pc, 16)) {
|
| + PrintError(js, "Must specify code address: code/%sc0deadd0.",
|
| + kCollectedPrefix);
|
| return true;
|
| }
|
| + return HandleNullCode(pc, js);
|
| }
|
| - ASSERT(js->num_arguments() == 2);
|
| - if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
|
| - PrintError(js, "Must specify code address: code/c0deadd0.");
|
| - return true;
|
| + if (strncmp(kNativePrefix, command, kNativePrefixLen) == 0) {
|
| + if (!GetUnsignedIntegerId(&command[kNativePrefixLen], &pc, 16)) {
|
| + PrintError(js, "Must specify code address: code/%sc0deadd0.",
|
| + kNativePrefix);
|
| + return true;
|
| + }
|
| + // TODO(johnmccutchan): Support native Code.
|
| + return HandleNullCode(pc, js);
|
| }
|
| - Code& code = Code::Handle();
|
| - code ^= Code::LookupCode(pc);
|
| - if (!code.IsNull()) {
|
| - code.PrintToJSONStream(js, false);
|
| + if (strncmp(kReusedPrefix, command, kReusedPrefixLen) == 0) {
|
| + if (!GetUnsignedIntegerId(&command[kReusedPrefixLen], &pc, 16)) {
|
| + PrintError(js, "Must specify code address: code/%sc0deadd0.",
|
| + kReusedPrefix);
|
| + return true;
|
| + }
|
| + return HandleNullCode(pc, js);
|
| + }
|
| + int64_t timestamp = 0;
|
| + if (!GetCodeId(command, ×tamp, &pc) || (timestamp < 0)) {
|
| + PrintError(js, "Malformed code id: %s", command);
|
| return true;
|
| }
|
| - code ^= Code::LookupCodeInVmIsolate(pc);
|
| + Code& code = Code::Handle(Code::FindCode(pc, timestamp));
|
| if (!code.IsNull()) {
|
| code.PrintToJSONStream(js, false);
|
| return true;
|
| }
|
| - PrintError(js, "Could not find code at %" Px "", pc);
|
| + PrintError(js, "Could not find code with id: %s", command);
|
| return true;
|
| }
|
|
|
|
|