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 "platform/address_sanitizer.h" | 5 #include "platform/address_sanitizer.h" |
6 #include "platform/memory_sanitizer.h" | 6 #include "platform/memory_sanitizer.h" |
7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
8 | 8 |
9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
10 #include "vm/atomic.h" | 10 #include "vm/atomic.h" |
11 #include "vm/code_patcher.h" | 11 #include "vm/code_patcher.h" |
12 #include "vm/debugger.h" | |
13 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
14 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
15 #include "vm/json_stream.h" | 14 #include "vm/json_stream.h" |
16 #include "vm/lockers.h" | 15 #include "vm/lockers.h" |
17 #include "vm/message_handler.h" | |
18 #include "vm/native_symbol.h" | 16 #include "vm/native_symbol.h" |
19 #include "vm/object.h" | 17 #include "vm/object.h" |
20 #include "vm/os.h" | 18 #include "vm/os.h" |
21 #include "vm/profiler.h" | 19 #include "vm/profiler.h" |
22 #include "vm/reusable_handles.h" | 20 #include "vm/reusable_handles.h" |
23 #include "vm/signal_handler.h" | 21 #include "vm/signal_handler.h" |
24 #include "vm/simulator.h" | 22 #include "vm/simulator.h" |
25 #include "vm/stack_frame.h" | 23 #include "vm/stack_frame.h" |
26 | 24 |
27 namespace dart { | 25 namespace dart { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 void Profiler::SetSamplePeriod(intptr_t period) { | 97 void Profiler::SetSamplePeriod(intptr_t period) { |
100 const int kMinimumProfilePeriod = 50; | 98 const int kMinimumProfilePeriod = 50; |
101 if (period < kMinimumProfilePeriod) { | 99 if (period < kMinimumProfilePeriod) { |
102 FLAG_profile_period = kMinimumProfilePeriod; | 100 FLAG_profile_period = kMinimumProfilePeriod; |
103 } else { | 101 } else { |
104 FLAG_profile_period = period; | 102 FLAG_profile_period = period; |
105 } | 103 } |
106 } | 104 } |
107 | 105 |
108 | 106 |
| 107 void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) { |
| 108 if (!FLAG_profile) { |
| 109 return; |
| 110 } |
| 111 ASSERT(isolate == Isolate::Current()); |
| 112 ASSERT(isolate != NULL); |
| 113 ASSERT(sample_buffer_ != NULL); |
| 114 { |
| 115 MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); |
| 116 SampleBuffer* sample_buffer = sample_buffer_; |
| 117 if (!shared_buffer) { |
| 118 sample_buffer = new SampleBuffer(); |
| 119 } |
| 120 IsolateProfilerData* profiler_data = |
| 121 new IsolateProfilerData(sample_buffer, !shared_buffer); |
| 122 ASSERT(profiler_data != NULL); |
| 123 isolate->set_profiler_data(profiler_data); |
| 124 if (FLAG_trace_profiled_isolates) { |
| 125 OS::Print("Profiler Setup %p %s\n", isolate, isolate->name()); |
| 126 } |
| 127 } |
| 128 BeginExecution(isolate); |
| 129 } |
| 130 |
| 131 |
| 132 void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) { |
| 133 ASSERT(isolate != NULL); |
| 134 if (!FLAG_profile) { |
| 135 return; |
| 136 } |
| 137 // We do not have a current isolate. |
| 138 ASSERT(Isolate::Current() == NULL); |
| 139 { |
| 140 MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); |
| 141 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
| 142 if (profiler_data == NULL) { |
| 143 // Already freed. |
| 144 return; |
| 145 } |
| 146 isolate->set_profiler_data(NULL); |
| 147 delete profiler_data; |
| 148 if (FLAG_trace_profiled_isolates) { |
| 149 OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name()); |
| 150 } |
| 151 } |
| 152 } |
| 153 |
| 154 |
| 155 void Profiler::BeginExecution(Isolate* isolate) { |
| 156 if (isolate == NULL) { |
| 157 return; |
| 158 } |
| 159 if (!FLAG_profile) { |
| 160 return; |
| 161 } |
| 162 ASSERT(initialized_); |
| 163 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
| 164 if (profiler_data == NULL) { |
| 165 return; |
| 166 } |
| 167 Thread* thread = Thread::Current(); |
| 168 thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread); |
| 169 ThreadInterrupter::WakeUp(); |
| 170 } |
| 171 |
| 172 |
| 173 void Profiler::EndExecution(Isolate* isolate) { |
| 174 if (isolate == NULL) { |
| 175 return; |
| 176 } |
| 177 if (!FLAG_profile) { |
| 178 return; |
| 179 } |
| 180 ASSERT(initialized_); |
| 181 Thread* thread = Thread::Current(); |
| 182 thread->SetThreadInterrupter(NULL, NULL); |
| 183 } |
| 184 |
| 185 |
| 186 IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer, |
| 187 bool own_sample_buffer) { |
| 188 ASSERT(sample_buffer != NULL); |
| 189 sample_buffer_ = sample_buffer; |
| 190 own_sample_buffer_ = own_sample_buffer; |
| 191 block_count_ = 0; |
| 192 } |
| 193 |
| 194 |
| 195 IsolateProfilerData::~IsolateProfilerData() { |
| 196 if (own_sample_buffer_) { |
| 197 delete sample_buffer_; |
| 198 sample_buffer_ = NULL; |
| 199 own_sample_buffer_ = false; |
| 200 } |
| 201 } |
| 202 |
| 203 |
| 204 void IsolateProfilerData::Block() { |
| 205 block_count_++; |
| 206 } |
| 207 |
| 208 |
| 209 void IsolateProfilerData::Unblock() { |
| 210 block_count_--; |
| 211 if (block_count_ < 0) { |
| 212 FATAL("Too many calls to Dart_IsolateUnblocked."); |
| 213 } |
| 214 if (!blocked()) { |
| 215 // We just unblocked this isolate, wake up the thread interrupter. |
| 216 ThreadInterrupter::WakeUp(); |
| 217 } |
| 218 } |
| 219 |
| 220 |
109 intptr_t Sample::pcs_length_ = 0; | 221 intptr_t Sample::pcs_length_ = 0; |
110 intptr_t Sample::instance_size_ = 0; | 222 intptr_t Sample::instance_size_ = 0; |
111 | 223 |
112 | 224 |
113 void Sample::InitOnce() { | 225 void Sample::InitOnce() { |
114 pcs_length_ = kSampleSize; | 226 pcs_length_ = kSampleSize; |
115 instance_size_ = | 227 instance_size_ = |
116 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. | 228 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. |
117 } | 229 } |
118 | 230 |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 | 810 |
699 if (in_dart_code) { | 811 if (in_dart_code) { |
700 // We can only trust the stack pointer if we are executing Dart code. | 812 // We can only trust the stack pointer if we are executing Dart code. |
701 // See http://dartbug.com/20421 for details. | 813 // See http://dartbug.com/20421 for details. |
702 CopyStackBuffer(sample, sp); | 814 CopyStackBuffer(sample, sp); |
703 } | 815 } |
704 | 816 |
705 if (FLAG_profile_vm) { | 817 if (FLAG_profile_vm) { |
706 // Always walk the native stack collecting both native and Dart frames. | 818 // Always walk the native stack collecting both native and Dart frames. |
707 native_stack_walker->walk(); | 819 native_stack_walker->walk(); |
708 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 820 } else if (exited_dart_code) { |
709 // We have a valid exit frame info, use the Dart stack walker. | 821 // We have a valid exit frame info, use the Dart stack walker. |
710 dart_exit_stack_walker->walk(); | 822 dart_exit_stack_walker->walk(); |
711 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 823 } else if (in_dart_code) { |
712 // We are executing Dart code. We have frame pointers. | 824 // We are executing Dart code. We have frame pointers. |
713 dart_stack_walker->walk(); | 825 dart_stack_walker->walk(); |
714 } else { | 826 } else { |
715 sample->set_vm_tag(VMTag::kEmbedderTagId); | 827 sample->set_vm_tag(VMTag::kEmbedderTagId); |
716 sample->SetAt(0, pc); | 828 sample->SetAt(0, pc); |
717 } | 829 } |
718 | 830 |
719 #if defined(TARGET_OS_WINDOWS) | 831 #if defined(TARGET_OS_WINDOWS) |
720 // Use structured exception handling to trap guard page access. | 832 // Use structured exception handling to trap guard page access. |
721 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { | 833 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { |
(...skipping 10 matching lines...) Expand all Loading... |
732 new_protect, | 844 new_protect, |
733 &old_protect); | 845 &old_protect); |
734 USE(success); | 846 USE(success); |
735 ASSERT(success); | 847 ASSERT(success); |
736 ASSERT(old_protect == PAGE_READWRITE); | 848 ASSERT(old_protect == PAGE_READWRITE); |
737 } | 849 } |
738 #endif | 850 #endif |
739 } | 851 } |
740 | 852 |
741 | 853 |
| 854 // Is |thread| executing Dart code? |
| 855 static bool ExecutingDart(Thread* thread) { |
| 856 ASSERT(thread != NULL); |
| 857 return (thread->top_exit_frame_info() == 0) && |
| 858 (thread->vm_tag() == VMTag::kDartTagId); |
| 859 } |
| 860 |
| 861 |
| 862 // Has |thread| exited Dart code? |
| 863 static bool ExitedDart(Thread* thread) { |
| 864 return (thread->top_exit_frame_info() != 0) && |
| 865 (thread->vm_tag() != VMTag::kDartTagId); |
| 866 } |
| 867 |
| 868 |
742 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within | 869 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within |
743 // it. Return |false| if anything looks suspicious. | 870 // it. Return |false| if anything looks suspicious. |
744 static bool GetAndValidateIsolateStackBounds(Thread* thread, | 871 static bool GetAndValidateIsolateStackBounds(Thread* thread, |
| 872 uintptr_t sp, |
745 uintptr_t fp, | 873 uintptr_t fp, |
746 uintptr_t sp, | |
747 uword* stack_lower, | 874 uword* stack_lower, |
748 uword* stack_upper) { | 875 uword* stack_upper) { |
749 ASSERT(thread != NULL); | 876 ASSERT(thread != NULL); |
750 Isolate* isolate = thread->isolate(); | 877 Isolate* isolate = thread->isolate(); |
751 ASSERT(isolate != NULL); | 878 ASSERT(isolate != NULL); |
752 ASSERT(stack_lower != NULL); | 879 ASSERT(stack_lower != NULL); |
753 ASSERT(stack_upper != NULL); | 880 ASSERT(stack_upper != NULL); |
754 #if defined(USING_SIMULATOR) | 881 #if defined(USING_SIMULATOR) |
755 const bool in_dart_code = thread->IsExecutingDartCode(); | 882 const bool in_dart_code = ExecutingDart(thread); |
756 if (in_dart_code) { | 883 if (in_dart_code) { |
757 Simulator* simulator = isolate->simulator(); | 884 Simulator* simulator = isolate->simulator(); |
758 *stack_lower = simulator->StackBase(); | 885 *stack_lower = simulator->StackBase(); |
759 *stack_upper = simulator->StackTop(); | 886 *stack_upper = simulator->StackTop(); |
760 } else if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper)) { | 887 } else if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper)) { |
761 // Could not get stack boundary. | 888 // Could not get stack boundary. |
762 return false; | 889 return false; |
763 } | 890 } |
764 if ((*stack_lower == 0) || (*stack_upper == 0)) { | 891 if ((*stack_lower == 0) || (*stack_upper == 0)) { |
765 return false; | 892 return false; |
(...skipping 22 matching lines...) Expand all Loading... |
788 | 915 |
789 if ((fp < *stack_lower) || (fp >= *stack_upper)) { | 916 if ((fp < *stack_lower) || (fp >= *stack_upper)) { |
790 // Frame pointer is outside isolate stack boundary. | 917 // Frame pointer is outside isolate stack boundary. |
791 return false; | 918 return false; |
792 } | 919 } |
793 | 920 |
794 return true; | 921 return true; |
795 } | 922 } |
796 | 923 |
797 | 924 |
798 // Some simple sanity checking of |pc|, |fp|, and |sp|. | 925 // Some simple sanity checking of |pc|, |sp|, and |fp|. |
799 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) { | 926 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) { |
800 if ((sp == 0) || (fp == 0) || (pc == 0)) { | 927 if ((sp == 0) || (fp == 0) || (pc == 0)) { |
801 // None of these registers should be zero. | 928 // None of these registers should be zero. |
802 return false; | 929 return false; |
803 } | 930 } |
804 | 931 |
805 if (sp > fp) { | 932 if (sp > fp) { |
806 // Assuming the stack grows down, we should never have a stack pointer above | 933 // Assuming the stack grows down, we should never have a stack pointer above |
807 // the frame pointer. | 934 // the frame pointer. |
808 return false; | 935 return false; |
809 } | 936 } |
810 | 937 |
811 return true; | 938 return true; |
812 } | 939 } |
813 | 940 |
814 | 941 |
| 942 // Return |isolate|'s sample buffer. |
| 943 static SampleBuffer* GetSampleBuffer(Isolate* isolate) { |
| 944 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
| 945 if (profiler_data == NULL) { |
| 946 // Profiler not initialized. |
| 947 return NULL; |
| 948 } |
| 949 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); |
| 950 return sample_buffer; |
| 951 } |
| 952 |
| 953 |
815 static Sample* SetupSample(Thread* thread, | 954 static Sample* SetupSample(Thread* thread, |
816 SampleBuffer* sample_buffer, | 955 SampleBuffer* sample_buffer, |
817 ThreadId tid) { | 956 ThreadId tid) { |
818 ASSERT(thread != NULL); | 957 ASSERT(thread != NULL); |
819 Isolate* isolate = thread->isolate(); | 958 Isolate* isolate = thread->isolate(); |
820 ASSERT(sample_buffer != NULL); | 959 ASSERT(sample_buffer != NULL); |
821 Sample* sample = sample_buffer->ReserveSample(); | 960 Sample* sample = sample_buffer->ReserveSample(); |
822 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid); | 961 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid); |
823 uword vm_tag = thread->vm_tag(); | 962 uword vm_tag = thread->vm_tag(); |
824 #if defined(USING_SIMULATOR) | 963 #if defined(USING_SIMULATOR) |
825 // When running in the simulator, the runtime entry function address | 964 // When running in the simulator, the runtime entry function address |
826 // (stored as the vm tag) is the address of a redirect function. | 965 // (stored as the vm tag) is the address of a redirect function. |
827 // Attempt to find the real runtime entry function address and use that. | 966 // Attempt to find the real runtime entry function address and use that. |
828 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); | 967 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); |
829 if (redirect_vm_tag != 0) { | 968 if (redirect_vm_tag != 0) { |
830 vm_tag = redirect_vm_tag; | 969 vm_tag = redirect_vm_tag; |
831 } | 970 } |
832 #endif | 971 #endif |
833 sample->set_vm_tag(vm_tag); | 972 sample->set_vm_tag(vm_tag); |
834 sample->set_user_tag(isolate->user_tag()); | 973 sample->set_user_tag(isolate->user_tag()); |
835 return sample; | 974 return sample; |
836 } | 975 } |
837 | 976 |
838 | 977 |
839 static bool CheckIsolate(Isolate* isolate) { | 978 static bool CheckIsolate(Isolate* isolate) { |
840 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { | 979 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
841 // No isolate. | 980 // No isolate. |
842 return false; | 981 return false; |
843 } | 982 } |
844 return isolate != Dart::vm_isolate(); | 983 ASSERT(isolate != Dart::vm_isolate()); |
| 984 return true; |
845 } | 985 } |
846 | 986 |
847 | 987 |
848 #if defined(TARGET_OS_WINDOWS) | 988 #if defined(TARGET_OS_WINDOWS) |
849 __declspec(noinline) | 989 __declspec(noinline) |
850 static uintptr_t GetProgramCounter() { | 990 static uintptr_t GetProgramCounter() { |
851 return reinterpret_cast<uintptr_t>(_ReturnAddress()); | 991 return reinterpret_cast<uintptr_t>(_ReturnAddress()); |
852 } | 992 } |
853 #else | 993 #else |
854 static uintptr_t __attribute__((noinline)) GetProgramCounter() { | 994 static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
855 return reinterpret_cast<uintptr_t>( | 995 return reinterpret_cast<uintptr_t>( |
856 __builtin_extract_return_addr(__builtin_return_address(0))); | 996 __builtin_extract_return_addr(__builtin_return_address(0))); |
857 } | 997 } |
858 #endif | 998 #endif |
859 | 999 |
860 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { | 1000 void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { |
861 ASSERT(thread != NULL); | 1001 ASSERT(thread != NULL); |
862 Isolate* isolate = thread->isolate(); | 1002 Isolate* isolate = thread->isolate(); |
863 if (!CheckIsolate(isolate)) { | 1003 if (!CheckIsolate(isolate)) { |
864 return; | 1004 return; |
865 } | 1005 } |
866 | 1006 |
867 const bool exited_dart_code = thread->HasExitedDartCode(); | 1007 const bool exited_dart_code = ExitedDart(thread); |
868 | 1008 |
869 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | 1009 SampleBuffer* sample_buffer = GetSampleBuffer(isolate); |
870 if (sample_buffer == NULL) { | 1010 if (sample_buffer == NULL) { |
871 // Profiler not initialized. | 1011 // Profiler not initialized. |
872 return; | 1012 return; |
873 } | 1013 } |
874 | 1014 |
875 if (FLAG_profile_vm) { | 1015 if (FLAG_profile_vm) { |
876 uintptr_t sp = Isolate::GetCurrentStackPointer(); | 1016 uintptr_t sp = Isolate::GetCurrentStackPointer(); |
877 uintptr_t fp = 0; | 1017 uintptr_t fp = 0; |
878 uintptr_t pc = GetProgramCounter(); | 1018 uintptr_t pc = GetProgramCounter(); |
879 | 1019 |
880 COPY_FP_REGISTER(fp); | 1020 COPY_FP_REGISTER(fp); |
881 | 1021 |
882 uword stack_lower = 0; | 1022 uword stack_lower = 0; |
883 uword stack_upper = 0; | 1023 uword stack_upper = 0; |
884 | 1024 |
885 if (!InitialRegisterCheck(pc, fp, sp)) { | 1025 if (!InitialRegisterCheck(pc, sp, fp)) { |
886 return; | 1026 return; |
887 } | 1027 } |
888 | 1028 |
889 if (!GetAndValidateIsolateStackBounds(thread, | 1029 if (!GetAndValidateIsolateStackBounds(thread, |
| 1030 sp, |
890 fp, | 1031 fp, |
891 sp, | |
892 &stack_lower, | 1032 &stack_lower, |
893 &stack_upper)) { | 1033 &stack_upper)) { |
894 // Could not get stack boundary. | 1034 // Could not get stack boundary. |
895 return; | 1035 return; |
896 } | 1036 } |
897 | 1037 |
898 Sample* sample = SetupSample(thread, | 1038 Sample* sample = SetupSample(thread, |
899 sample_buffer, | 1039 sample_buffer, |
900 OSThread::GetCurrentThreadId()); | 1040 OSThread::GetCurrentThreadId()); |
901 sample->SetAllocationCid(cid); | 1041 sample->SetAllocationCid(cid); |
(...skipping 22 matching lines...) Expand all Loading... |
924 Sample* sample = SetupSample(thread, | 1064 Sample* sample = SetupSample(thread, |
925 sample_buffer, | 1065 sample_buffer, |
926 OSThread::GetCurrentThreadId()); | 1066 OSThread::GetCurrentThreadId()); |
927 sample->SetAllocationCid(cid); | 1067 sample->SetAllocationCid(cid); |
928 sample->set_vm_tag(VMTag::kEmbedderTagId); | 1068 sample->set_vm_tag(VMTag::kEmbedderTagId); |
929 sample->SetAt(0, pc); | 1069 sample->SetAt(0, pc); |
930 } | 1070 } |
931 } | 1071 } |
932 | 1072 |
933 | 1073 |
934 void Profiler::SampleThread(Thread* thread, | 1074 void Profiler::RecordSampleInterruptCallback( |
935 const InterruptedThreadState& state) { | 1075 const InterruptedThreadState& state, |
936 if (StubCode::HasBeenInitialized() && | 1076 void* data) { |
937 StubCode::InJumpToExceptionHandlerStub(state.pc)) { | 1077 Thread* thread = reinterpret_cast<Thread*>(data); |
938 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | 1078 Isolate* isolate = thread->isolate(); |
939 // frame pointer, and some isolate state before jumping to a catch entry. | 1079 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
940 // It is not safe to walk the stack when executing this stub. | 1080 // No isolate. |
| 1081 return; |
| 1082 } |
| 1083 ASSERT(isolate != Dart::vm_isolate()); |
| 1084 |
| 1085 SampleBuffer* sample_buffer = GetSampleBuffer(isolate); |
| 1086 if (sample_buffer == NULL) { |
| 1087 // Profiler not initialized. |
941 return; | 1088 return; |
942 } | 1089 } |
943 | 1090 |
944 const bool in_dart_code = thread->IsExecutingDartCode(); | 1091 const bool exited_dart_code = ExitedDart(thread); |
| 1092 const bool in_dart_code = ExecutingDart(thread); |
945 | 1093 |
946 uintptr_t sp = 0; | 1094 uintptr_t sp = 0; |
947 uintptr_t fp = state.fp; | 1095 uintptr_t fp = state.fp; |
948 uintptr_t pc = state.pc; | 1096 uintptr_t pc = state.pc; |
949 #if defined(USING_SIMULATOR) | 1097 #if defined(USING_SIMULATOR) |
950 Simulator* simulator = NULL; | 1098 Simulator* simulator = NULL; |
951 #endif | 1099 #endif |
952 | 1100 |
953 ASSERT(thread != NULL); | |
954 Isolate* isolate = thread->isolate(); | |
955 | |
956 if (in_dart_code) { | 1101 if (in_dart_code) { |
957 // If we're in Dart code, use the Dart stack pointer. | 1102 // If we're in Dart code, use the Dart stack pointer. |
958 #if defined(USING_SIMULATOR) | 1103 #if defined(USING_SIMULATOR) |
959 simulator = isolate->simulator(); | 1104 simulator = isolate->simulator(); |
960 sp = simulator->get_register(SPREG); | 1105 sp = simulator->get_register(SPREG); |
961 fp = simulator->get_register(FPREG); | 1106 fp = simulator->get_register(FPREG); |
962 pc = simulator->get_pc(); | 1107 pc = simulator->get_pc(); |
963 #else | 1108 #else |
964 sp = state.dsp; | 1109 sp = state.dsp; |
965 #endif | 1110 #endif |
966 } else { | 1111 } else { |
967 // If we're in runtime code, use the C stack pointer. | 1112 // If we're in runtime code, use the C stack pointer. |
968 sp = state.csp; | 1113 sp = state.csp; |
969 } | 1114 } |
970 | 1115 |
971 if (!InitialRegisterCheck(pc, fp, sp)) { | 1116 if (!InitialRegisterCheck(pc, sp, fp)) { |
972 return; | 1117 return; |
973 } | 1118 } |
974 | 1119 |
975 if (!CheckIsolate(isolate)) { | 1120 if (StubCode::InJumpToExceptionHandlerStub(pc)) { |
976 return; | 1121 // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
977 } | 1122 // frame pointer, and some isolate state before jumping to a catch entry. |
978 | 1123 // It is not safe to walk the stack when executing this stub. |
979 if (!thread->IsMutatorThread()) { | |
980 // Not a mutator thread. | |
981 // TODO(johnmccutchan): Profile all threads with an isolate. | |
982 return; | 1124 return; |
983 } | 1125 } |
984 | 1126 |
985 uword stack_lower = 0; | 1127 uword stack_lower = 0; |
986 uword stack_upper = 0; | 1128 uword stack_upper = 0; |
987 if (!GetAndValidateIsolateStackBounds(thread, | 1129 if (!GetAndValidateIsolateStackBounds(thread, |
| 1130 sp, |
988 fp, | 1131 fp, |
989 sp, | |
990 &stack_lower, | 1132 &stack_lower, |
991 &stack_upper)) { | 1133 &stack_upper)) { |
992 // Could not get stack boundary. | 1134 // Could not get stack boundary. |
993 return; | 1135 return; |
994 } | 1136 } |
995 | 1137 |
996 // At this point we have a valid stack boundary for this isolate and | 1138 // At this point we have a valid stack boundary for this isolate and |
997 // know that our initial stack and frame pointers are within the boundary. | 1139 // know that our initial stack and frame pointers are within the boundary. |
998 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | |
999 if (sample_buffer == NULL) { | |
1000 // Profiler not initialized. | |
1001 return; | |
1002 } | |
1003 | 1140 |
1004 // Setup sample. | 1141 // Setup sample. |
1005 Sample* sample = SetupSample(thread, | 1142 Sample* sample = SetupSample(thread, |
1006 sample_buffer, | 1143 sample_buffer, |
1007 OSThread::GetCurrentThreadId()); | 1144 OSThread::GetCurrentThreadId()); |
1008 // Increment counter for vm tag. | 1145 // Increment counter for vm tag. |
1009 VMTagCounters* counters = isolate->vm_tag_counters(); | 1146 VMTagCounters* counters = isolate->vm_tag_counters(); |
1010 ASSERT(counters != NULL); | 1147 ASSERT(counters != NULL); |
1011 counters->Increment(sample->vm_tag()); | 1148 counters->Increment(sample->vm_tag()); |
1012 | 1149 |
(...skipping 13 matching lines...) Expand all Loading... |
1026 | 1163 |
1027 ProfilerDartStackWalker dart_stack_walker(isolate, | 1164 ProfilerDartStackWalker dart_stack_walker(isolate, |
1028 sample, | 1165 sample, |
1029 sample_buffer, | 1166 sample_buffer, |
1030 stack_lower, | 1167 stack_lower, |
1031 stack_upper, | 1168 stack_upper, |
1032 pc, | 1169 pc, |
1033 fp, | 1170 fp, |
1034 sp); | 1171 sp); |
1035 | 1172 |
1036 const bool exited_dart_code = thread->HasExitedDartCode(); | |
1037 | |
1038 // All memory access is done inside CollectSample. | 1173 // All memory access is done inside CollectSample. |
1039 CollectSample(isolate, | 1174 CollectSample(isolate, |
1040 exited_dart_code, | 1175 exited_dart_code, |
1041 in_dart_code, | 1176 in_dart_code, |
1042 sample, | 1177 sample, |
1043 &native_stack_walker, | 1178 &native_stack_walker, |
1044 &dart_exit_stack_walker, | 1179 &dart_exit_stack_walker, |
1045 &dart_stack_walker, | 1180 &dart_stack_walker, |
1046 pc, | 1181 pc, |
1047 fp, | 1182 fp, |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 uword pc) { | 1394 uword pc) { |
1260 return vm_isolate->heap()->CodeContains(pc) | 1395 return vm_isolate->heap()->CodeContains(pc) |
1261 || isolate->heap()->CodeContains(pc); | 1396 || isolate->heap()->CodeContains(pc); |
1262 } | 1397 } |
1263 | 1398 |
1264 | 1399 |
1265 ProcessedSampleBuffer::ProcessedSampleBuffer() { | 1400 ProcessedSampleBuffer::ProcessedSampleBuffer() { |
1266 } | 1401 } |
1267 | 1402 |
1268 } // namespace dart | 1403 } // namespace dart |
OLD | NEW |