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 "bin/vmstats_impl.h" | 5 #include "bin/vmstats_impl.h" |
| 6 | 6 |
| 7 #include "bin/file.h" | 7 #include "bin/file.h" |
| 8 #include "bin/log.h" | 8 #include "bin/log.h" |
| 9 #include "bin/platform.h" | 9 #include "bin/platform.h" |
| 10 #include "bin/resources.h" | 10 #include "bin/resources.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 dart::Monitor* VmStats::instance_monitor_; | 26 dart::Monitor* VmStats::instance_monitor_; |
| 27 dart::Mutex* VmStatusService::mutex_; | 27 dart::Mutex* VmStatusService::mutex_; |
| 28 | 28 |
| 29 | 29 |
| 30 void VmStats::Start(int port, const char* root_dir) { | 30 void VmStats::Start(int port, const char* root_dir) { |
| 31 if (instance_ != NULL) { | 31 if (instance_ != NULL) { |
| 32 FATAL("VmStats already started."); | 32 FATAL("VmStats already started."); |
| 33 } | 33 } |
| 34 instance_ = new VmStats(); | 34 instance_ = new VmStats(); |
| 35 instance_monitor_ = new dart::Monitor(); | 35 instance_monitor_ = new dart::Monitor(); |
| 36 Initialize(); | |
| 37 | |
| 38 if (port != 0) { | |
| 39 StartServer(port, root_dir); | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 | |
| 44 void VmStats::StartServer(int port, const char* root_dir) { | |
| 36 VmStatusService::InitOnce(); | 45 VmStatusService::InitOnce(); |
| 37 Socket::Initialize(); | 46 Socket::Initialize(); |
| 38 | 47 |
| 39 if (root_dir != NULL) { | 48 if (root_dir != NULL) { |
| 40 instance_->root_directory_ = root_dir; | 49 instance_->root_directory_ = root_dir; |
| 41 } | 50 } |
| 42 | 51 |
| 43 // TODO(tball): allow host to be specified. | 52 // TODO(tball): allow host to be specified. |
| 44 char* host = const_cast<char*>(DEFAULT_HOST); | 53 char* host = const_cast<char*>(DEFAULT_HOST); |
| 45 OSError* os_error; | 54 OSError* os_error; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 61 | 70 |
| 62 MonitorLocker ml(instance_monitor_); | 71 MonitorLocker ml(instance_monitor_); |
| 63 instance_->running_ = true; | 72 instance_->running_ = true; |
| 64 int err = dart::Thread::Start(WebServer, address); | 73 int err = dart::Thread::Start(WebServer, address); |
| 65 if (err != 0) { | 74 if (err != 0) { |
| 66 Log::PrintErr("Failed starting VmStats thread: %d\n", err); | 75 Log::PrintErr("Failed starting VmStats thread: %d\n", err); |
| 67 Shutdown(); | 76 Shutdown(); |
| 68 } | 77 } |
| 69 } | 78 } |
| 70 | 79 |
| 71 | |
| 72 void VmStats::Stop() { | 80 void VmStats::Stop() { |
| 73 ASSERT(instance_ != NULL); | 81 ASSERT(instance_ != NULL); |
| 74 MonitorLocker ml(instance_monitor_); | 82 MonitorLocker ml(instance_monitor_); |
| 75 instance_->running_ = false; | 83 instance_->running_ = false; |
| 76 } | 84 } |
| 77 | 85 |
| 78 | 86 |
| 79 void VmStats::Shutdown() { | 87 void VmStats::Shutdown() { |
| 80 ASSERT(instance_ != NULL); | 88 ASSERT(instance_ != NULL); |
| 81 MonitorLocker ml(instance_monitor_); | 89 MonitorLocker ml(instance_monitor_); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 } | 328 } |
| 321 first = false; | 329 first = false; |
| 322 free(status); | 330 free(status); |
| 323 } | 331 } |
| 324 } | 332 } |
| 325 text.AddString("\n]\n}\n"); | 333 text.AddString("\n]\n}\n"); |
| 326 return strdup(text.buf()); | 334 return strdup(text.buf()); |
| 327 } | 335 } |
| 328 | 336 |
| 329 | 337 |
| 338 // Advance the scanner to the value token of a specified name-value pair. | |
| 339 void SeekNamedValue(const char* name, dart::JSONScanner* scanner) { | |
| 340 while (!scanner->EOM()) { | |
| 341 scanner->Scan(); | |
| 342 if (scanner->IsStringLiteral(name)) { | |
| 343 scanner->Scan(); | |
| 344 ASSERT(scanner->CurrentToken() == dart::JSONScanner::TokenColon); | |
| 345 scanner->Scan(); | |
| 346 return; | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 void VmStats::DumpStack() { | |
| 352 Log::Print("Isolate dump:\n"); | |
| 353 IsolateTable::iterator itr; | |
| 354 MonitorLocker ml(instance_monitor_); | |
|
siva
2013/04/05 15:55:09
This could lead to potential deadlocks if the sign
| |
| 355 for (itr = instance_->isolate_table_.begin(); | |
| 356 itr != instance_->isolate_table_.end(); ++itr) { | |
| 357 Dart_Isolate isolate = itr->second; | |
| 358 | |
| 359 // Print isolate name and details. | |
| 360 static char buffer[512]; | |
| 361 snprintf(buffer, sizeof(buffer), | |
| 362 "/isolate/0x%"Px, reinterpret_cast<intptr_t>(isolate)); | |
| 363 char* isolate_details = VmStatusService::GetVmStatus(buffer); | |
| 364 if (isolate_details != NULL) { | |
| 365 dart::JSONScanner scanner(isolate_details); | |
| 366 SeekNamedValue("name", &scanner); | |
| 367 char* name = strndup(scanner.TokenChars(), scanner.TokenLen()); | |
| 368 SeekNamedValue("port", &scanner); | |
| 369 char* port = strndup(scanner.TokenChars(), scanner.TokenLen()); | |
| 370 Log::Print("\"%s\" port=%s\n", name, port); | |
| 371 free(isolate_details); | |
| 372 free(port); | |
| 373 free(name); | |
| 374 } | |
| 375 | |
| 376 // Print stack trace. | |
| 377 snprintf(buffer, sizeof(buffer), | |
| 378 "/isolate/0x%"Px"/stacktrace", | |
| 379 reinterpret_cast<intptr_t>(isolate)); | |
| 380 char* trace = VmStatusService::GetVmStatus(buffer); | |
|
siva
2013/04/05 15:55:09
I assume this schedules an interrupt on the isolat
| |
| 381 if (trace != NULL) { | |
| 382 dart::JSONScanner scanner(trace); | |
| 383 SeekNamedValue("url", &scanner); | |
| 384 char* url = strndup(scanner.TokenChars(), scanner.TokenLen()); | |
| 385 SeekNamedValue("line", &scanner); | |
| 386 char* line = strndup(scanner.TokenChars(), scanner.TokenLen()); | |
| 387 SeekNamedValue("function", &scanner); | |
| 388 char* function = strndup(scanner.TokenChars(), scanner.TokenLen()); | |
| 389 Log::Print(" at %s(%s:%s)\n", function, url, line); | |
| 390 free(trace); | |
| 391 free(url); | |
| 392 free(line); | |
| 393 free(function); | |
| 394 } | |
| 395 } | |
| 396 } | |
| 397 | |
| 398 | |
| 330 // Global static pointer used to ensure a single instance of the class. | 399 // Global static pointer used to ensure a single instance of the class. |
| 331 VmStatusService* VmStatusService::instance_ = NULL; | 400 VmStatusService* VmStatusService::instance_ = NULL; |
| 332 | 401 |
| 333 | 402 |
| 334 void VmStatusService::InitOnce() { | 403 void VmStatusService::InitOnce() { |
| 335 ASSERT(VmStatusService::instance_ == NULL); | 404 ASSERT(VmStatusService::instance_ == NULL); |
| 336 VmStatusService::instance_ = new VmStatusService(); | 405 VmStatusService::instance_ = new VmStatusService(); |
| 337 VmStatusService::mutex_ = new dart::Mutex(); | 406 VmStatusService::mutex_ = new dart::Mutex(); |
| 338 | 407 |
| 339 // Register built-in status plug-ins. RegisterPlugin is not used because | 408 // Register built-in status plug-ins. RegisterPlugin is not used because |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 365 VmStatusPlugin* plugin = instance_->registered_plugin_list_; | 434 VmStatusPlugin* plugin = instance_->registered_plugin_list_; |
| 366 while (plugin != NULL) { | 435 while (plugin != NULL) { |
| 367 char* result = (plugin->callback())(request); | 436 char* result = (plugin->callback())(request); |
| 368 if (result != NULL) { | 437 if (result != NULL) { |
| 369 return result; | 438 return result; |
| 370 } | 439 } |
| 371 plugin = plugin->next(); | 440 plugin = plugin->next(); |
| 372 } | 441 } |
| 373 return NULL; | 442 return NULL; |
| 374 } | 443 } |
| OLD | NEW |