Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: runtime/vm/isolate.cc

Issue 13587008: Updated VM stacktrace support (20898) with strndup impl. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/isolate.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/isolate.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "platform/json.h"
9 #include "lib/mirrors.h" 10 #include "lib/mirrors.h"
10 #include "vm/code_observers.h" 11 #include "vm/code_observers.h"
11 #include "vm/compiler_stats.h" 12 #include "vm/compiler_stats.h"
12 #include "vm/dart_api_state.h" 13 #include "vm/dart_api_state.h"
13 #include "vm/dart_entry.h" 14 #include "vm/dart_entry.h"
14 #include "vm/debugger.h" 15 #include "vm/debugger.h"
15 #include "vm/heap.h" 16 #include "vm/heap.h"
16 #include "vm/message_handler.h" 17 #include "vm/message_handler.h"
17 #include "vm/object_store.h" 18 #include "vm/object_store.h"
18 #include "vm/parser.h" 19 #include "vm/parser.h"
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 stack_limit_(0), 336 stack_limit_(0),
336 saved_stack_limit_(0), 337 saved_stack_limit_(0),
337 message_handler_(NULL), 338 message_handler_(NULL),
338 spawn_data_(0), 339 spawn_data_(0),
339 gc_prologue_callbacks_(), 340 gc_prologue_callbacks_(),
340 gc_epilogue_callbacks_(), 341 gc_epilogue_callbacks_(),
341 deopt_cpu_registers_copy_(NULL), 342 deopt_cpu_registers_copy_(NULL),
342 deopt_fpu_registers_copy_(NULL), 343 deopt_fpu_registers_copy_(NULL),
343 deopt_frame_copy_(NULL), 344 deopt_frame_copy_(NULL),
344 deopt_frame_copy_size_(0), 345 deopt_frame_copy_size_(0),
345 deferred_objects_(NULL) { 346 deferred_objects_(NULL),
347 stacktrace_(NULL),
348 stack_frame_index_(-1) {
346 } 349 }
347 350
348 351
349 Isolate::~Isolate() { 352 Isolate::~Isolate() {
350 delete [] name_; 353 delete [] name_;
351 delete heap_; 354 delete heap_;
352 delete object_store_; 355 delete object_store_;
353 delete api_state_; 356 delete api_state_;
354 delete stub_code_; 357 delete stub_code_;
355 delete debugger_; 358 delete debugger_;
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 631
629 632
630 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; 633 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL;
631 Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL; 634 Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL;
632 Dart_IsolateUnhandledExceptionCallback 635 Dart_IsolateUnhandledExceptionCallback
633 Isolate::unhandled_exception_callback_ = NULL; 636 Isolate::unhandled_exception_callback_ = NULL;
634 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; 637 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL;
635 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL; 638 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL;
636 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL; 639 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL;
637 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL; 640 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL;
641 Dart_IsolateInterruptCallback Isolate::vmstats_callback_ = NULL;
638 642
639 643
640 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, 644 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
641 bool visit_prologue_weak_handles, 645 bool visit_prologue_weak_handles,
642 bool validate_frames) { 646 bool validate_frames) {
643 ASSERT(visitor != NULL); 647 ASSERT(visitor != NULL);
644 648
645 // Visit objects in the object store. 649 // Visit objects in the object store.
646 object_store()->VisitObjectPointers(visitor); 650 object_store()->VisitObjectPointers(visitor);
647 651
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 686
683 687
684 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, 688 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor,
685 bool visit_prologue_weak_handles) { 689 bool visit_prologue_weak_handles) {
686 if (api_state() != NULL) { 690 if (api_state() != NULL) {
687 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); 691 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles);
688 } 692 }
689 } 693 }
690 694
691 695
696 static Monitor* status_sync = NULL;
697
698
699 bool Isolate::FetchStacktrace() {
700 Isolate* isolate = Isolate::Current();
701 MonitorLocker ml(status_sync);
702 DebuggerStackTrace* stack = Debugger::CollectStackTrace();
703 TextBuffer buffer(256);
704 buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"stacktrace\": [ ",
705 reinterpret_cast<int64_t>(isolate));
706 intptr_t n_frames = stack->Length();
707 String& url = String::Handle();
708 String& function = String::Handle();
709 for (int i = 0; i < n_frames; i++) {
710 if (i > 0) {
711 buffer.Printf(", ");
712 }
713 ActivationFrame* frame = stack->ActivationFrameAt(i);
714 url ^= frame->SourceUrl();
715 function ^= frame->function().UserVisibleName();
716 buffer.Printf("{ \"url\": \"%s\", ", url.ToCString());
717 buffer.Printf("\"line\": %"Pd", ", frame->LineNumber());
718 buffer.Printf("\"function\": \"%s\", ", function.ToCString());
719
720 const Code& code = frame->code();
721 buffer.Printf("\"code\": { ");
722 buffer.Printf("\"alive\": %s, ", code.is_alive() ? "false" : "true");
723 buffer.Printf("\"optimized\": %s }}",
724 code.is_optimized() ? "false" : "true");
725 }
726 buffer.Printf("]}");
727 isolate->stacktrace_ = strndup(buffer.buf(), buffer.length());
728 ml.Notify();
729 return true;
730 }
731
732
733 bool Isolate::FetchStackFrameDetails() {
734 Isolate* isolate = Isolate::Current();
735 ASSERT(isolate->stack_frame_index_ >= 0);
736 MonitorLocker ml(status_sync);
737 DebuggerStackTrace* stack = Debugger::CollectStackTrace();
738 intptr_t frame_index = isolate->stack_frame_index_;
739 if (frame_index >= stack->Length()) {
740 // Frame no longer available.
741 return NULL;
742 }
743 ActivationFrame* frame = stack->ActivationFrameAt(frame_index);
744 TextBuffer buffer(256);
745 buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"frame_index\": %"Pd", ",
746 reinterpret_cast<int64_t>(isolate), frame_index);
747
748 const Code& code = frame->code();
749 buffer.Printf("\"code\": { \"size\": %"Pd", ", code.Size());
750 buffer.Printf("\"alive\": %s, ", code.is_alive() ? "false" : "true");
751 buffer.Printf("\"optimized\": %s }, ",
752 code.is_optimized() ? "false" : "true");
753 // TODO(tball): add compilation stats (time, etc.), when available.
754
755 buffer.Printf("\"local_vars\": [ ");
756 intptr_t n_local_vars = frame->NumLocalVariables();
757 String& var_name = String::Handle();
758 Instance& value = Instance::Handle();
759 for (int i = 0; i < n_local_vars; i++) {
760 if (i > 0) {
761 buffer.Printf(", ");
762 }
763 intptr_t token_pos, end_pos;
764 frame->VariableAt(i, &var_name, &token_pos, &end_pos, &value);
765 buffer.Printf(
766 "{ \"name\": \"%s\", \"pos\": %"Pd", \"end_pos\": %"Pd", "
767 "\"value\": \"%s\" }",
768 var_name.ToCString(), token_pos, end_pos, value.ToCString());
769 }
770 buffer.Printf("]}");
771 isolate->stacktrace_ = strndup(buffer.buf(), buffer.length());
772 ml.Notify();
773 return true;
774 }
775
776
777 char* Isolate::DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb) {
778 ASSERT(stacktrace_ == NULL);
779 SetVmStatsCallback(cb);
780 if (status_sync == NULL) {
781 status_sync = new Monitor();
782 }
783 ScheduleInterrupts(Isolate::kVmStatusInterrupt);
784 {
785 MonitorLocker ml(status_sync);
786 if (stacktrace_ == NULL) { // It may already be available.
787 ml.Wait();
788 }
789 }
790 SetVmStatsCallback(NULL);
791 ASSERT(stacktrace_ != NULL);
792 // result is freed by VmStats::WebServer().
793 char* result = stacktrace_;
794 stacktrace_ = NULL;
795 return result;
796 }
797
798
799 char* Isolate::GetStatusStacktrace() {
800 return DoStacktraceInterrupt(&FetchStacktrace);
801 }
802
803 char* Isolate::GetStatusStackFrame(intptr_t index) {
804 ASSERT(index >= 0);
805 stack_frame_index_ = index;
806 char* result = DoStacktraceInterrupt(&FetchStackFrameDetails);
807 stack_frame_index_ = -1;
808 return result;
809 }
810
811
812 // Returns the isolate's general detail information.
813 char* Isolate::GetStatusDetails() {
814 const char* format = "{\n"
815 " \"handle\": \"0x%"Px64"\",\n"
816 " \"name\": \"%s\",\n"
817 " \"port\": %"Pd",\n"
818 " \"starttime\": %"Pd",\n"
819 " \"stacklimit\": %"Pd",\n"
820 " \"newspace\": {\n"
821 " \"used\": %"Pd",\n"
822 " \"capacity\": %"Pd"\n"
823 " },\n"
824 " \"oldspace\": {\n"
825 " \"used\": %"Pd",\n"
826 " \"capacity\": %"Pd"\n"
827 " }\n"
828 "}";
829 char buffer[300];
830 int64_t address = reinterpret_cast<int64_t>(this);
831 int n = OS::SNPrint(buffer, 300, format, address, name(), main_port(),
832 (start_time() / 1000L), saved_stack_limit(),
833 heap()->Used(Heap::kNew) / KB,
834 heap()->Capacity(Heap::kNew) / KB,
835 heap()->Used(Heap::kOld) / KB,
836 heap()->Capacity(Heap::kOld) / KB);
837 ASSERT(n < 300);
838 return strdup(buffer);
839 }
840
841
692 char* Isolate::GetStatus(const char* request) { 842 char* Isolate::GetStatus(const char* request) {
693 char* p = const_cast<char*>(request); 843 char* p = const_cast<char*>(request);
694 const char* service_type = "/isolate/"; 844 const char* service_type = "/isolate/";
695 ASSERT(strncmp(p, service_type, strlen(service_type)) == 0); 845 ASSERT(!strncmp(p, service_type, strlen(service_type)));
696 p += strlen(service_type); 846 p += strlen(service_type);
697 847
698 // Extract isolate handle. 848 // Extract isolate handle.
699 int64_t addr; 849 int64_t addr;
700 OS::StringToInt64(p, &addr); 850 OS::StringToInt64(p, &addr);
851 // TODO(tball): add validity check when issue 9600 is fixed.
701 Isolate* isolate = reinterpret_cast<Isolate*>(addr); 852 Isolate* isolate = reinterpret_cast<Isolate*>(addr);
702 Heap* heap = isolate->heap(); 853 p += strcspn(p, "/");
703 854
704 char buffer[256]; 855 // Query "/isolate/<handle>".
705 int64_t port = isolate->main_port(); 856 if (strlen(p) == 0) {
706 int64_t start_time = (isolate->start_time() / 1000L); 857 return isolate->GetStatusDetails();
707 #if defined(TARGET_ARCH_X64) 858 }
708 const char* format = "{\n" 859
709 " \"name\": \"%s\",\n" 860 // Query "/isolate/<handle>/stacktrace"
710 " \"port\": %ld,\n" 861 if (!strcmp(p, "/stacktrace")) {
711 " \"starttime\": %ld,\n" 862 return isolate->GetStatusStacktrace();
712 " \"stacklimit\": %ld,\n" 863 }
713 " \"newspace\": {\n" 864
714 " \"used\": %ld,\n" 865 // Query "/isolate/<handle>/stacktrace/<frame-index>"
715 " \"capacity\": %ld\n" 866 const char* stacktrace_query = "/stacktrace/";
716 " },\n" 867 int64_t frame_index = -1;
717 " \"oldspace\": {\n" 868 if (!strncmp(p, stacktrace_query, strlen(stacktrace_query))) {
718 " \"used\": %ld,\n" 869 p += strlen(stacktrace_query);
719 " \"capacity\": %ld\n" 870 OS::StringToInt64(p, &frame_index);
720 " }\n" 871 if (frame_index >= 0) {
721 "}"; 872 return isolate->GetStatusStackFrame(frame_index);
722 #else 873 }
723 const char* format = "{\n" 874 }
724 " \"name\": \"%s\",\n" 875
725 " \"port\": %lld,\n" 876 // TODO(tball): "/isolate/<handle>/stacktrace/<frame-index>"/disassemble"
726 " \"starttime\": %lld,\n" 877
727 " \"stacklimit\": %d,\n" 878 return NULL; // Unimplemented query.
728 " \"newspace\": {\n"
729 " \"used\": %d,\n"
730 " \"capacity\": %d\n"
731 " },\n"
732 " \"oldspace\": {\n"
733 " \"used\": %d,\n"
734 " \"capacity\": %d\n"
735 " }\n"
736 "}";
737 #endif
738 int n = OS::SNPrint(buffer, 256, format, isolate->name(), port, start_time,
739 isolate->saved_stack_limit(),
740 heap->Used(Heap::kNew) / KB,
741 heap->Capacity(Heap::kNew) / KB,
742 heap->Used(Heap::kOld) / KB,
743 heap->Capacity(Heap::kOld) / KB);
744 ASSERT(n < 256);
745 return strdup(buffer);
746 } 879 }
747 880
748 } // namespace dart 881 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698