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 isolate->stacktrace_ = strdup(Exceptions::CreateStackTrace()); |
| 700 ml.Notify(); |
| 701 return true; |
| 702 } |
| 703 |
| 704 |
| 705 const char* Isolate::GetStatusStacktrace() { |
| 706 Dart_IsolateInterruptCallback saved_callback = InterruptCallback(); |
| 707 SetInterruptCallback(&FetchStacktrace); |
| 708 status_sync = new Monitor(); |
| 709 ScheduleInterrupts(Isolate::kApiInterrupt); |
| 710 { |
| 711 MonitorLocker ml(status_sync); |
| 712 ml.Wait(); |
| 713 } |
| 714 SetInterruptCallback(saved_callback); |
| 715 delete status_sync; |
| 716 status_sync = NULL; |
| 717 ASSERT(stacktrace_ != NULL); |
| 718 |
| 719 const char* json_format = "{ \"handle\": \"0x%"Px64"\", \"stacktrace\": \""; |
| 720 TextBuffer buffer(strlen(json_format) + strlen(stacktrace_)); |
| 721 buffer.Printf(json_format, reinterpret_cast<int64_t>(this)); |
| 722 buffer.AddEscapedString(stacktrace_); |
| 723 free(const_cast<char*>(stacktrace_)); |
| 724 stacktrace_ = NULL; |
| 725 buffer.Printf("\" }"); |
| 726 return strndup(buffer.buf(), buffer.length()); |
| 727 } |
| 728 |
| 729 |
692 char* Isolate::GetStatus(const char* request) { | 730 char* Isolate::GetStatus(const char* request) { |
693 char* p = const_cast<char*>(request); | 731 char* p = const_cast<char*>(request); |
694 const char* service_type = "/isolate/"; | 732 const char* service_type = "/isolate/"; |
695 ASSERT(strncmp(p, service_type, strlen(service_type)) == 0); | 733 ASSERT(!strncmp(p, service_type, strlen(service_type))); |
696 p += strlen(service_type); | 734 p += strlen(service_type); |
697 | 735 |
698 // Extract isolate handle. | 736 // Extract isolate handle. |
699 int64_t addr; | 737 int64_t addr; |
700 OS::StringToInt64(p, &addr); | 738 OS::StringToInt64(p, &addr); |
701 Isolate* isolate = reinterpret_cast<Isolate*>(addr); | 739 Isolate* isolate = reinterpret_cast<Isolate*>(addr); |
702 Heap* heap = isolate->heap(); | 740 p += strcspn(p, "/"); |
703 | 741 |
704 char buffer[256]; | 742 const char* trace_request = "/stacktrace"; |
705 int64_t port = isolate->main_port(); | 743 if (!strncmp(p, trace_request, strlen(trace_request))) { |
706 int64_t start_time = (isolate->start_time() / 1000L); | 744 return const_cast<char*>(isolate->GetStatusStacktrace()); |
707 #if defined(TARGET_ARCH_X64) | 745 } else { |
708 const char* format = "{\n" | 746 const char* name = isolate->name(); |
709 " \"name\": \"%s\",\n" | 747 int64_t port = isolate->main_port(); |
710 " \"port\": %ld,\n" | 748 int64_t start_time = (isolate->start_time() / 1000L); |
711 " \"starttime\": %ld,\n" | 749 Heap* heap = isolate->heap(); |
712 " \"stacklimit\": %ld,\n" | 750 const char* format = "{\n" |
713 " \"newspace\": {\n" | 751 " \"handle\": \"0x%"Px64"\",\n" |
714 " \"used\": %ld,\n" | 752 " \"name\": \"%s\",\n" |
715 " \"capacity\": %ld\n" | 753 " \"port\": %"Pd",\n" |
716 " },\n" | 754 " \"starttime\": %"Pd",\n" |
717 " \"oldspace\": {\n" | 755 " \"stacklimit\": %"Pd",\n" |
718 " \"used\": %ld,\n" | 756 " \"newspace\": {\n" |
719 " \"capacity\": %ld\n" | 757 " \"used\": %"Pd",\n" |
720 " }\n" | 758 " \"capacity\": %"Pd"\n" |
721 "}"; | 759 " },\n" |
722 #else | 760 " \"oldspace\": {\n" |
723 const char* format = "{\n" | 761 " \"used\": %"Pd",\n" |
724 " \"name\": \"%s\",\n" | 762 " \"capacity\": %"Pd"\n" |
725 " \"port\": %lld,\n" | 763 " }\n" |
726 " \"starttime\": %lld,\n" | 764 "}"; |
727 " \"stacklimit\": %d,\n" | 765 char buffer[300]; |
728 " \"newspace\": {\n" | 766 int n = OS::SNPrint(buffer, 300, format, addr, name, port, start_time, |
729 " \"used\": %d,\n" | 767 isolate->saved_stack_limit(), |
730 " \"capacity\": %d\n" | 768 heap->Used(Heap::kNew) / KB, |
731 " },\n" | 769 heap->Capacity(Heap::kNew) / KB, |
732 " \"oldspace\": {\n" | 770 heap->Used(Heap::kOld) / KB, |
733 " \"used\": %d,\n" | 771 heap->Capacity(Heap::kOld) / KB); |
734 " \"capacity\": %d\n" | 772 ASSERT(n < 300); |
735 " }\n" | 773 return strdup(buffer); |
736 "}"; | 774 } |
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 } | 775 } |
747 | 776 |
748 } // namespace dart | 777 } // namespace dart |
OLD | NEW |