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 "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 Loading... | |
| 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) { | |
| 346 } | 348 } |
| 347 | 349 |
| 348 | 350 |
| 349 Isolate::~Isolate() { | 351 Isolate::~Isolate() { |
| 350 delete [] name_; | 352 delete [] name_; |
| 351 delete heap_; | 353 delete heap_; |
| 352 delete object_store_; | 354 delete object_store_; |
| 353 delete api_state_; | 355 delete api_state_; |
| 354 delete stub_code_; | 356 delete stub_code_; |
| 355 delete debugger_; | 357 delete debugger_; |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 | 684 |
| 683 | 685 |
| 684 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, | 686 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor, |
| 685 bool visit_prologue_weak_handles) { | 687 bool visit_prologue_weak_handles) { |
| 686 if (api_state() != NULL) { | 688 if (api_state() != NULL) { |
| 687 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); | 689 api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles); |
| 688 } | 690 } |
| 689 } | 691 } |
| 690 | 692 |
| 691 | 693 |
| 694 static Monitor* status_sync; | |
| 695 | |
| 696 bool Isolate::FetchStacktrace() { | |
| 697 Isolate* isolate = reinterpret_cast<Isolate*>(Dart_CurrentIsolate()); | |
| 698 MonitorLocker ml(status_sync); | |
| 699 DebuggerStackTrace* stack = Debugger::CollectStackTrace(); | |
| 700 TextBuffer buffer(256); | |
| 701 buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"stacktrace\": [ ", | |
| 702 reinterpret_cast<int64_t>(isolate)); | |
| 703 intptr_t n_frames = stack->Length(); | |
| 704 for (int i = 0; i < n_frames; i++) { | |
| 705 if (i > 0) { | |
| 706 buffer.Printf(", "); | |
| 707 } | |
| 708 ActivationFrame* frame = stack->ActivationFrameAt(i); | |
| 709 const String& url = String::Handle(frame->SourceUrl()); | |
| 710 const String& function = | |
| 711 String::Handle(frame->function().UserVisibleName()); | |
|
siva
2013/03/28 22:09:00
These handle creations can be hoisted outside the
Tom Ball
2013/03/29 22:39:32
Good idea -- done.
| |
| 712 buffer.Printf("{ \"url\": \"%s\", ", url.ToCString()); | |
| 713 buffer.Printf("\"line\": %d, ", frame->LineNumber()); | |
| 714 buffer.Printf("\"function\": \"%s\", ", function.ToCString()); | |
|
siva
2013/03/28 22:09:00
We probably also need the code object associated w
Tom Ball
2013/03/29 22:39:32
I added a "code": { "alive": bool, "optimized": bo
| |
| 715 buffer.Printf("\"local_vars\": [ "); | |
| 716 intptr_t n_local_vars = frame->NumLocalVariables(); | |
|
siva
2013/03/28 22:09:00
Do we need a detailed local variable list for each
Tom Ball
2013/03/29 22:39:32
As we discussed, I removed this section in favor o
| |
| 717 for (int j = 0; j < n_local_vars; j++) { | |
| 718 if (j > 0) { | |
| 719 buffer.Printf(", "); | |
| 720 } | |
| 721 String& var_name = String::Handle(); | |
| 722 Instance& value = Instance::Handle(); | |
|
siva
2013/03/28 22:09:00
These handle creations can be hoisted outside the
Tom Ball
2013/03/29 22:39:32
Done.
| |
| 723 intptr_t token_pos, end_pos; | |
| 724 frame->VariableAt(j, &var_name, &token_pos, &end_pos, &value); | |
| 725 buffer.Printf( | |
| 726 "{ \"name\": \"%s\", \"pos\": %d, \"end_pos\": %d, " | |
| 727 "\"value\": \"%s\" }", | |
| 728 var_name.ToCString(), token_pos, end_pos, value.ToCString()); | |
| 729 } | |
| 730 buffer.Printf("]}"); | |
| 731 } | |
| 732 buffer.Printf("]}"); | |
| 733 isolate->stacktrace_ = strndup(buffer.buf(), buffer.length()); | |
|
siva
2013/03/28 22:09:00
Who is responsible for freeing stacktrace_ ?
Tom Ball
2013/03/29 22:39:32
VmStats::WebService(), after the returned status i
| |
| 734 ml.Notify(); | |
| 735 return true; | |
| 736 } | |
| 737 | |
| 738 | |
| 739 const char* Isolate::GetStatusStacktrace() { | |
| 740 Dart_IsolateInterruptCallback saved_callback = InterruptCallback(); | |
| 741 SetInterruptCallback(&FetchStacktrace); | |
| 742 status_sync = new Monitor(); | |
|
siva
2013/03/28 22:09:00
Why do we allocate a new monitor for each stack tr
Tom Ball
2013/03/29 22:39:32
We don't -- I was being overly conservative. Now t
| |
| 743 ScheduleInterrupts(Isolate::kApiInterrupt); | |
|
siva
2013/03/28 22:09:00
Not sure if kApiInterrupt bit is the right one to
Tom Ball
2013/03/29 22:39:32
I don't know, but copied what the debugger does --
| |
| 744 { | |
| 745 MonitorLocker ml(status_sync); | |
| 746 ml.Wait(); | |
| 747 } | |
| 748 SetInterruptCallback(saved_callback); | |
| 749 delete status_sync; | |
| 750 status_sync = NULL; | |
| 751 ASSERT(stacktrace_ != NULL); | |
| 752 const char* result = stacktrace_; | |
| 753 stacktrace_ = NULL; | |
| 754 return result; | |
| 755 } | |
| 756 | |
| 757 | |
| 692 char* Isolate::GetStatus(const char* request) { | 758 char* Isolate::GetStatus(const char* request) { |
| 693 char* p = const_cast<char*>(request); | 759 char* p = const_cast<char*>(request); |
| 694 const char* service_type = "/isolate/"; | 760 const char* service_type = "/isolate/"; |
| 695 ASSERT(strncmp(p, service_type, strlen(service_type)) == 0); | 761 ASSERT(!strncmp(p, service_type, strlen(service_type))); |
| 696 p += strlen(service_type); | 762 p += strlen(service_type); |
| 697 | 763 |
| 698 // Extract isolate handle. | 764 // Extract isolate handle. |
| 699 int64_t addr; | 765 int64_t addr; |
| 700 OS::StringToInt64(p, &addr); | 766 OS::StringToInt64(p, &addr); |
| 701 Isolate* isolate = reinterpret_cast<Isolate*>(addr); | 767 Isolate* isolate = reinterpret_cast<Isolate*>(addr); |
| 702 Heap* heap = isolate->heap(); | 768 p += strcspn(p, "/"); |
| 703 | 769 |
| 704 char buffer[256]; | 770 const char* trace_request = "/stacktrace"; |
| 705 int64_t port = isolate->main_port(); | 771 if (!strncmp(p, trace_request, strlen(trace_request))) { |
|
siva
2013/03/28 22:09:00
It might be easier for adding new commands if we m
Tom Ball
2013/03/29 22:39:32
It's not quite a table, but GetStatus() now just p
| |
| 706 int64_t start_time = (isolate->start_time() / 1000L); | 772 return const_cast<char*>(isolate->GetStatusStacktrace()); |
| 707 #if defined(TARGET_ARCH_X64) | 773 } else { |
| 708 const char* format = "{\n" | 774 const char* name = isolate->name(); |
| 709 " \"name\": \"%s\",\n" | 775 int64_t port = isolate->main_port(); |
| 710 " \"port\": %ld,\n" | 776 int64_t start_time = (isolate->start_time() / 1000L); |
| 711 " \"starttime\": %ld,\n" | 777 Heap* heap = isolate->heap(); |
| 712 " \"stacklimit\": %ld,\n" | 778 const char* format = "{\n" |
| 713 " \"newspace\": {\n" | 779 " \"handle\": \"0x%"Px64"\",\n" |
| 714 " \"used\": %ld,\n" | 780 " \"name\": \"%s\",\n" |
| 715 " \"capacity\": %ld\n" | 781 " \"port\": %"Pd",\n" |
| 716 " },\n" | 782 " \"starttime\": %"Pd",\n" |
| 717 " \"oldspace\": {\n" | 783 " \"stacklimit\": %"Pd",\n" |
| 718 " \"used\": %ld,\n" | 784 " \"newspace\": {\n" |
| 719 " \"capacity\": %ld\n" | 785 " \"used\": %"Pd",\n" |
| 720 " }\n" | 786 " \"capacity\": %"Pd"\n" |
| 721 "}"; | 787 " },\n" |
| 722 #else | 788 " \"oldspace\": {\n" |
| 723 const char* format = "{\n" | 789 " \"used\": %"Pd",\n" |
| 724 " \"name\": \"%s\",\n" | 790 " \"capacity\": %"Pd"\n" |
| 725 " \"port\": %lld,\n" | 791 " }\n" |
| 726 " \"starttime\": %lld,\n" | 792 "}"; |
| 727 " \"stacklimit\": %d,\n" | 793 char buffer[300]; |
| 728 " \"newspace\": {\n" | 794 int n = OS::SNPrint(buffer, 300, format, addr, name, port, start_time, |
| 729 " \"used\": %d,\n" | 795 isolate->saved_stack_limit(), |
| 730 " \"capacity\": %d\n" | 796 heap->Used(Heap::kNew) / KB, |
| 731 " },\n" | 797 heap->Capacity(Heap::kNew) / KB, |
| 732 " \"oldspace\": {\n" | 798 heap->Used(Heap::kOld) / KB, |
| 733 " \"used\": %d,\n" | 799 heap->Capacity(Heap::kOld) / KB); |
| 734 " \"capacity\": %d\n" | 800 ASSERT(n < 300); |
| 735 " }\n" | 801 return strdup(buffer); |
| 736 "}"; | 802 } |
| 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 } | 803 } |
| 747 | 804 |
| 748 } // namespace dart | 805 } // namespace dart |
| OLD | NEW |