| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 | 132 |
| 133 bool Profiler::paused_ = false; | 133 bool Profiler::paused_ = false; |
| 134 | 134 |
| 135 | 135 |
| 136 // | 136 // |
| 137 // Ticker used to provide ticks to the profiler and the sliding state | 137 // Ticker used to provide ticks to the profiler and the sliding state |
| 138 // window. | 138 // window. |
| 139 // | 139 // |
| 140 class Ticker: public Sampler { | 140 class Ticker: public Sampler { |
| 141 public: | 141 public: |
| 142 explicit Ticker(int interval): | 142 explicit Ticker(int interval, unsigned int low_stack_bound): |
| 143 Sampler(interval, FLAG_prof), window_(NULL), profiler_(NULL) {} | 143 Sampler(interval, FLAG_prof), window_(NULL), profiler_(NULL), |
| 144 low_stack_bound_(low_stack_bound) {} |
| 144 | 145 |
| 145 ~Ticker() { if (IsActive()) Stop(); } | 146 ~Ticker() { if (IsActive()) Stop(); } |
| 146 | 147 |
| 147 void Tick(TickSample* sample) { | 148 void Tick(TickSample* sample) { |
| 149 if (IsProfiling()) SampleStack(sample); |
| 148 if (profiler_) profiler_->Insert(sample); | 150 if (profiler_) profiler_->Insert(sample); |
| 149 if (window_) window_->AddState(sample->state); | 151 if (window_) window_->AddState(sample->state); |
| 150 } | 152 } |
| 151 | 153 |
| 152 void SetWindow(SlidingStateWindow* window) { | 154 void SetWindow(SlidingStateWindow* window) { |
| 153 window_ = window; | 155 window_ = window; |
| 154 if (!IsActive()) Start(); | 156 if (!IsActive()) Start(); |
| 155 } | 157 } |
| 156 | 158 |
| 157 void ClearWindow() { | 159 void ClearWindow() { |
| 158 window_ = NULL; | 160 window_ = NULL; |
| 159 if (!profiler_ && IsActive()) Stop(); | 161 if (!profiler_ && IsActive()) Stop(); |
| 160 } | 162 } |
| 161 | 163 |
| 162 void SetProfiler(Profiler* profiler) { | 164 void SetProfiler(Profiler* profiler) { |
| 163 profiler_ = profiler; | 165 profiler_ = profiler; |
| 164 if (!IsActive()) Start(); | 166 if (!IsActive()) Start(); |
| 165 } | 167 } |
| 166 | 168 |
| 167 void ClearProfiler() { | 169 void ClearProfiler() { |
| 168 profiler_ = NULL; | 170 profiler_ = NULL; |
| 169 if (!window_ && IsActive()) Stop(); | 171 if (!window_ && IsActive()) Stop(); |
| 170 } | 172 } |
| 171 | 173 |
| 172 private: | 174 private: |
| 175 void SampleStack(TickSample* sample) { |
| 176 // Assuming that stack grows from lower addresses |
| 177 if (sample->sp < sample->fp && sample->fp < low_stack_bound_) { |
| 178 sample->InitStack(1); |
| 179 sample->stack[0] = Memory::Address_at( |
| 180 (Address)(sample->fp + StandardFrameConstants::kCallerPCOffset)); |
| 181 } else { |
| 182 // FP seems to be in some intermediate state, better discard this sample |
| 183 sample->InitStack(0); |
| 184 } |
| 185 } |
| 186 |
| 173 SlidingStateWindow* window_; | 187 SlidingStateWindow* window_; |
| 174 Profiler* profiler_; | 188 Profiler* profiler_; |
| 189 unsigned int low_stack_bound_; |
| 175 }; | 190 }; |
| 176 | 191 |
| 177 | 192 |
| 178 // | 193 // |
| 179 // SlidingStateWindow implementation. | 194 // SlidingStateWindow implementation. |
| 180 // | 195 // |
| 181 SlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) { | 196 SlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) { |
| 182 for (int i = 0; i < kBufferSize; i++) { | 197 for (int i = 0; i < kBufferSize; i++) { |
| 183 buffer_[i] = static_cast<byte>(OTHER); | 198 buffer_[i] = static_cast<byte>(OTHER); |
| 184 } | 199 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 247 |
| 233 void Profiler::Disengage() { | 248 void Profiler::Disengage() { |
| 234 // Stop receiving ticks. | 249 // Stop receiving ticks. |
| 235 Logger::ticker_->ClearProfiler(); | 250 Logger::ticker_->ClearProfiler(); |
| 236 | 251 |
| 237 // Terminate the worker thread by setting running_ to false, | 252 // Terminate the worker thread by setting running_ to false, |
| 238 // inserting a fake element in the queue and then wait for | 253 // inserting a fake element in the queue and then wait for |
| 239 // the thread to terminate. | 254 // the thread to terminate. |
| 240 running_ = false; | 255 running_ = false; |
| 241 TickSample sample; | 256 TickSample sample; |
| 242 sample.pc = 0; | |
| 243 sample.sp = 0; | |
| 244 sample.state = OTHER; | |
| 245 Insert(&sample); | 257 Insert(&sample); |
| 246 Join(); | 258 Join(); |
| 247 | 259 |
| 248 LOG(UncheckedStringEvent("profiler", "end")); | 260 LOG(UncheckedStringEvent("profiler", "end")); |
| 249 } | 261 } |
| 250 | 262 |
| 251 | 263 |
| 252 void Profiler::Run() { | 264 void Profiler::Run() { |
| 253 TickSample sample; | 265 TickSample sample; |
| 254 bool overflow = Logger::profiler_->Remove(&sample); | 266 bool overflow = Logger::profiler_->Remove(&sample); |
| (...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 | 905 |
| 894 #ifdef ENABLE_LOGGING_AND_PROFILING | 906 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 895 void Logger::TickEvent(TickSample* sample, bool overflow) { | 907 void Logger::TickEvent(TickSample* sample, bool overflow) { |
| 896 if (logfile_ == NULL || !FLAG_prof) return; | 908 if (logfile_ == NULL || !FLAG_prof) return; |
| 897 LogMessageBuilder msg; | 909 LogMessageBuilder msg; |
| 898 msg.Append("tick,0x%x,0x%x,%d", sample->pc, sample->sp, | 910 msg.Append("tick,0x%x,0x%x,%d", sample->pc, sample->sp, |
| 899 static_cast<int>(sample->state)); | 911 static_cast<int>(sample->state)); |
| 900 if (overflow) { | 912 if (overflow) { |
| 901 msg.Append(",overflow"); | 913 msg.Append(",overflow"); |
| 902 } | 914 } |
| 915 if (*(sample->stack)) { |
| 916 for (size_t i = 0; sample->stack[i]; ++i) { |
| 917 msg.Append(",0x%x", reinterpret_cast<unsigned int>(sample->stack[i])); |
| 918 } |
| 919 } |
| 903 msg.Append('\n'); | 920 msg.Append('\n'); |
| 904 msg.WriteToLogFile(); | 921 msg.WriteToLogFile(); |
| 905 } | 922 } |
| 906 | 923 |
| 907 | 924 |
| 908 bool Logger::IsProfilerPaused() { | 925 bool Logger::IsProfilerPaused() { |
| 909 return profiler_->paused(); | 926 return profiler_->paused(); |
| 910 } | 927 } |
| 911 | 928 |
| 912 | 929 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 logfile_ = OS::FOpen(*expanded, "w"); | 1000 logfile_ = OS::FOpen(*expanded, "w"); |
| 984 } else { | 1001 } else { |
| 985 logfile_ = OS::FOpen(FLAG_logfile, "w"); | 1002 logfile_ = OS::FOpen(FLAG_logfile, "w"); |
| 986 } | 1003 } |
| 987 message_buffer_ = NewArray<char>(kMessageBufferSize); | 1004 message_buffer_ = NewArray<char>(kMessageBufferSize); |
| 988 mutex_ = OS::CreateMutex(); | 1005 mutex_ = OS::CreateMutex(); |
| 989 } | 1006 } |
| 990 | 1007 |
| 991 current_state_ = new VMState(OTHER); | 1008 current_state_ = new VMState(OTHER); |
| 992 | 1009 |
| 993 ticker_ = new Ticker(10); | 1010 // as log is initialized early with V8, we can assume that JS execution |
| 1011 // frames can never reach this point on stack |
| 1012 int stack_var; |
| 1013 ticker_ = new Ticker(10, reinterpret_cast<unsigned int>(&stack_var)); |
| 994 | 1014 |
| 995 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { | 1015 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { |
| 996 sliding_state_window_ = new SlidingStateWindow(); | 1016 sliding_state_window_ = new SlidingStateWindow(); |
| 997 } | 1017 } |
| 998 | 1018 |
| 999 if (FLAG_prof) { | 1019 if (FLAG_prof) { |
| 1000 profiler_ = new Profiler(); | 1020 profiler_ = new Profiler(); |
| 1001 if (!FLAG_prof_auto) | 1021 if (!FLAG_prof_auto) |
| 1002 profiler_->pause(); | 1022 profiler_->pause(); |
| 1003 profiler_->Engage(); | 1023 profiler_->Engage(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 if (FLAG_log_state_changes) { | 1118 if (FLAG_log_state_changes) { |
| 1099 LOG(UncheckedStringEvent("Leaving", StateToString(state_))); | 1119 LOG(UncheckedStringEvent("Leaving", StateToString(state_))); |
| 1100 if (previous_) { | 1120 if (previous_) { |
| 1101 LOG(UncheckedStringEvent("To", StateToString(previous_->state_))); | 1121 LOG(UncheckedStringEvent("To", StateToString(previous_->state_))); |
| 1102 } | 1122 } |
| 1103 } | 1123 } |
| 1104 } | 1124 } |
| 1105 #endif | 1125 #endif |
| 1106 | 1126 |
| 1107 } } // namespace v8::internal | 1127 } } // namespace v8::internal |
| OLD | NEW |