Chromium Code Reviews| Index: runtime/bin/vmstats_impl.cc |
| =================================================================== |
| --- runtime/bin/vmstats_impl.cc (revision 20895) |
| +++ runtime/bin/vmstats_impl.cc (working copy) |
| @@ -33,6 +33,15 @@ |
| } |
| instance_ = new VmStats(); |
| instance_monitor_ = new dart::Monitor(); |
| + Initialize(); |
| + |
| + if (port != 0) { |
| + StartServer(port, root_dir); |
| + } |
| +} |
| + |
| + |
| +void VmStats::StartServer(int port, const char* root_dir) { |
| VmStatusService::InitOnce(); |
| Socket::Initialize(); |
| @@ -68,7 +77,6 @@ |
| } |
| } |
| - |
| void VmStats::Stop() { |
| ASSERT(instance_ != NULL); |
| MonitorLocker ml(instance_monitor_); |
| @@ -327,6 +335,75 @@ |
| } |
| +// Platform-independent version of strndup(), which Windows doesn't have. |
| +static char* Strndup(const char* s, intptr_t len) { |
| + char* dup = reinterpret_cast<char*>(malloc(len + 1)); |
| + strncpy(dup, s, len); |
| + dup[len] = '\0'; |
| + return dup; |
|
siva
2013/04/04 00:47:15
Please see comment in other CL about moving this a
Tom Ball
2013/04/04 20:05:53
Done.
|
| +} |
| + |
| + |
| +// Advance the scanner to the value token of a specified name-value pair. |
| +void SeekNamedValue(const char* name, dart::JSONScanner* scanner) { |
| + while (!scanner->EOM()) { |
| + scanner->Scan(); |
| + if (scanner->IsStringLiteral(name)) { |
| + scanner->Scan(); |
| + ASSERT(scanner->CurrentToken() == dart::JSONScanner::TokenColon); |
| + scanner->Scan(); |
| + return; |
| + } |
| + } |
| +} |
| + |
| +void VmStats::DumpStack() { |
| + Log::Print("Isolate dump:\n"); |
| + IsolateTable::iterator itr; |
| + for (itr = instance_->isolate_table_.begin(); |
| + itr != instance_->isolate_table_.end(); ++itr) { |
|
siva
2013/04/04 00:47:15
This map could potentially be changing while this
Tom Ball
2013/04/04 20:05:53
Right -- I added a MutexLocker.
|
| + Dart_Isolate isolate = itr->second; |
| + |
| + // Print isolate name and details. |
| + static char buffer[512]; |
| + snprintf(buffer, sizeof(buffer), |
| + "/isolate/0x%"Px, reinterpret_cast<intptr_t>(isolate)); |
| + char* isolate_details = VmStatusService::GetVmStatus(buffer); |
| + if (isolate_details != NULL) { |
| + dart::JSONScanner scanner(isolate_details); |
| + SeekNamedValue("name", &scanner); |
|
siva
2013/04/04 00:47:15
How come you are not using the JSONReader class wh
Tom Ball
2013/04/04 20:05:53
Its Seek is limited to top-level name-value pairs,
|
| + char* name = Strndup(scanner.TokenChars(), scanner.TokenLen()); |
| + SeekNamedValue("port", &scanner); |
| + char* port = Strndup(scanner.TokenChars(), scanner.TokenLen()); |
| + Log::Print("\"%s\" port=%s\n", name, port); |
| + free(isolate_details); |
| + free(port); |
| + free(name); |
| + } |
| + |
| + // Print stack trace. |
| + snprintf(buffer, sizeof(buffer), |
| + "/isolate/0x%"Px"/stacktrace", |
| + reinterpret_cast<intptr_t>(isolate)); |
| + char* trace = VmStatusService::GetVmStatus(buffer); |
| + if (trace != NULL) { |
| + dart::JSONScanner scanner(trace); |
| + SeekNamedValue("url", &scanner); |
| + char* url = Strndup(scanner.TokenChars(), scanner.TokenLen()); |
| + SeekNamedValue("line", &scanner); |
| + char* line = Strndup(scanner.TokenChars(), scanner.TokenLen()); |
| + SeekNamedValue("function", &scanner); |
| + char* function = Strndup(scanner.TokenChars(), scanner.TokenLen()); |
| + Log::Print(" at %s(%s:%s)\n", function, url, line); |
| + free(trace); |
| + free(url); |
| + free(line); |
| + free(function); |
| + } |
| + } |
| +} |
| + |
| + |
| // Global static pointer used to ensure a single instance of the class. |
| VmStatusService* VmStatusService::instance_ = NULL; |