| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <stdarg.h> | 28 #include <stdarg.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "log.h" | 33 #include "log.h" |
| 34 #include "log-utils.h" | |
| 35 #include "macro-assembler.h" | 34 #include "macro-assembler.h" |
| 36 #include "platform.h" | |
| 37 #include "serialize.h" | 35 #include "serialize.h" |
| 38 #include "string-stream.h" | 36 #include "string-stream.h" |
| 39 | 37 |
| 40 namespace v8 { | 38 namespace v8 { |
| 41 namespace internal { | 39 namespace internal { |
| 42 | 40 |
| 43 #ifdef ENABLE_LOGGING_AND_PROFILING | 41 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 44 | 42 |
| 45 // | 43 // |
| 46 // Sliding state window. Updates counters to keep track of the last | 44 // Sliding state window. Updates counters to keep track of the last |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 // | 295 // |
| 298 // Logger class implementation. | 296 // Logger class implementation. |
| 299 // | 297 // |
| 300 Ticker* Logger::ticker_ = NULL; | 298 Ticker* Logger::ticker_ = NULL; |
| 301 Profiler* Logger::profiler_ = NULL; | 299 Profiler* Logger::profiler_ = NULL; |
| 302 VMState* Logger::current_state_ = NULL; | 300 VMState* Logger::current_state_ = NULL; |
| 303 VMState Logger::bottom_state_(EXTERNAL); | 301 VMState Logger::bottom_state_(EXTERNAL); |
| 304 SlidingStateWindow* Logger::sliding_state_window_ = NULL; | 302 SlidingStateWindow* Logger::sliding_state_window_ = NULL; |
| 305 const char** Logger::log_events_ = NULL; | 303 const char** Logger::log_events_ = NULL; |
| 306 CompressionHelper* Logger::compression_helper_ = NULL; | 304 CompressionHelper* Logger::compression_helper_ = NULL; |
| 305 bool Logger::is_logging_ = false; |
| 307 | 306 |
| 308 #define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name, | 307 #define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name, |
| 309 const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 308 const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| 310 LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT) | 309 LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT) |
| 311 }; | 310 }; |
| 312 #undef DECLARE_LONG_EVENT | 311 #undef DECLARE_LONG_EVENT |
| 313 | 312 |
| 314 #define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name, | 313 #define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name, |
| 315 const char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 314 const char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| 316 LOG_EVENTS_AND_TAGS_LIST(DECLARE_SHORT_EVENT) | 315 LOG_EVENTS_AND_TAGS_LIST(DECLARE_SHORT_EVENT) |
| 317 }; | 316 }; |
| 318 #undef DECLARE_SHORT_EVENT | 317 #undef DECLARE_SHORT_EVENT |
| 319 | 318 |
| 320 | 319 |
| 321 bool Logger::IsEnabled() { | |
| 322 return Log::IsEnabled(); | |
| 323 } | |
| 324 | |
| 325 | |
| 326 void Logger::ProfilerBeginEvent() { | 320 void Logger::ProfilerBeginEvent() { |
| 327 if (!Log::IsEnabled()) return; | 321 if (!Log::IsEnabled()) return; |
| 328 LogMessageBuilder msg; | 322 LogMessageBuilder msg; |
| 329 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); | 323 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); |
| 330 if (FLAG_compress_log) { | 324 if (FLAG_compress_log) { |
| 331 msg.Append("profiler,\"compression\",%d\n", kCompressionWindowSize); | 325 msg.Append("profiler,\"compression\",%d\n", kCompressionWindowSize); |
| 332 } | 326 } |
| 333 msg.WriteToLogFile(); | 327 msg.WriteToLogFile(); |
| 334 } | 328 } |
| 335 | 329 |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 if (profiler_->paused()) { | 933 if (profiler_->paused()) { |
| 940 return; | 934 return; |
| 941 } | 935 } |
| 942 profiler_->pause(); | 936 profiler_->pause(); |
| 943 if (FLAG_prof_lazy) { | 937 if (FLAG_prof_lazy) { |
| 944 if (!FLAG_sliding_state_window) ticker_->Stop(); | 938 if (!FLAG_sliding_state_window) ticker_->Stop(); |
| 945 FLAG_log_code = false; | 939 FLAG_log_code = false; |
| 946 // Must be the same message as Log::kDynamicBufferSeal. | 940 // Must be the same message as Log::kDynamicBufferSeal. |
| 947 LOG(UncheckedStringEvent("profiler", "pause")); | 941 LOG(UncheckedStringEvent("profiler", "pause")); |
| 948 } | 942 } |
| 943 is_logging_ = false; |
| 949 } | 944 } |
| 950 | 945 |
| 951 | 946 |
| 952 void Logger::ResumeProfiler() { | 947 void Logger::ResumeProfiler() { |
| 953 if (!profiler_->paused() || !Log::IsEnabled()) { | 948 if (!profiler_->paused() || !Log::IsEnabled()) { |
| 954 return; | 949 return; |
| 955 } | 950 } |
| 951 is_logging_ = true; |
| 956 if (FLAG_prof_lazy) { | 952 if (FLAG_prof_lazy) { |
| 957 LOG(UncheckedStringEvent("profiler", "resume")); | 953 LOG(UncheckedStringEvent("profiler", "resume")); |
| 958 FLAG_log_code = true; | 954 FLAG_log_code = true; |
| 959 LogCompiledFunctions(); | 955 LogCompiledFunctions(); |
| 960 if (!FLAG_sliding_state_window) ticker_->Start(); | 956 if (!FLAG_sliding_state_window) ticker_->Start(); |
| 961 } | 957 } |
| 962 profiler_->resume(); | 958 profiler_->resume(); |
| 963 } | 959 } |
| 964 | 960 |
| 965 | 961 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 | 1058 |
| 1063 // --prof implies --log-code. | 1059 // --prof implies --log-code. |
| 1064 if (FLAG_prof) FLAG_log_code = true; | 1060 if (FLAG_prof) FLAG_log_code = true; |
| 1065 | 1061 |
| 1066 // --prof_lazy controls --log-code, implies --noprof_auto. | 1062 // --prof_lazy controls --log-code, implies --noprof_auto. |
| 1067 if (FLAG_prof_lazy) { | 1063 if (FLAG_prof_lazy) { |
| 1068 FLAG_log_code = false; | 1064 FLAG_log_code = false; |
| 1069 FLAG_prof_auto = false; | 1065 FLAG_prof_auto = false; |
| 1070 } | 1066 } |
| 1071 | 1067 |
| 1072 bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api | 1068 bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api |
| 1073 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect | 1069 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect |
| 1074 || FLAG_log_regexp || FLAG_log_state_changes || FLAG_prof_lazy; | 1070 || FLAG_log_regexp || FLAG_log_state_changes; |
| 1071 |
| 1072 bool open_log_file = start_logging || FLAG_prof_lazy; |
| 1075 | 1073 |
| 1076 // If we're logging anything, we need to open the log file. | 1074 // If we're logging anything, we need to open the log file. |
| 1077 if (open_log_file) { | 1075 if (open_log_file) { |
| 1078 if (strcmp(FLAG_logfile, "-") == 0) { | 1076 if (strcmp(FLAG_logfile, "-") == 0) { |
| 1079 Log::OpenStdout(); | 1077 Log::OpenStdout(); |
| 1080 } else if (strcmp(FLAG_logfile, "*") == 0) { | 1078 } else if (strcmp(FLAG_logfile, "*") == 0) { |
| 1081 Log::OpenMemoryBuffer(); | 1079 Log::OpenMemoryBuffer(); |
| 1082 } else if (strchr(FLAG_logfile, '%') != NULL) { | 1080 } else if (strchr(FLAG_logfile, '%') != NULL) { |
| 1083 // If there's a '%' in the log file name we have to expand | 1081 // If there's a '%' in the log file name we have to expand |
| 1084 // placeholders. | 1082 // placeholders. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { | 1125 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { |
| 1128 sliding_state_window_ = new SlidingStateWindow(); | 1126 sliding_state_window_ = new SlidingStateWindow(); |
| 1129 } | 1127 } |
| 1130 | 1128 |
| 1131 log_events_ = FLAG_compress_log ? | 1129 log_events_ = FLAG_compress_log ? |
| 1132 kCompressedLogEventsNames : kLongLogEventsNames; | 1130 kCompressedLogEventsNames : kLongLogEventsNames; |
| 1133 if (FLAG_compress_log) { | 1131 if (FLAG_compress_log) { |
| 1134 compression_helper_ = new CompressionHelper(kCompressionWindowSize); | 1132 compression_helper_ = new CompressionHelper(kCompressionWindowSize); |
| 1135 } | 1133 } |
| 1136 | 1134 |
| 1135 is_logging_ = start_logging; |
| 1136 |
| 1137 if (FLAG_prof) { | 1137 if (FLAG_prof) { |
| 1138 profiler_ = new Profiler(); | 1138 profiler_ = new Profiler(); |
| 1139 if (!FLAG_prof_auto) | 1139 if (!FLAG_prof_auto) { |
| 1140 profiler_->pause(); | 1140 profiler_->pause(); |
| 1141 } else { |
| 1142 is_logging_ = true; |
| 1143 } |
| 1141 profiler_->Engage(); | 1144 profiler_->Engage(); |
| 1142 } | 1145 } |
| 1143 | 1146 |
| 1144 LogMessageBuilder::set_write_failure_handler(StopLoggingAndProfiling); | 1147 LogMessageBuilder::set_write_failure_handler(StopLoggingAndProfiling); |
| 1145 | 1148 |
| 1146 return true; | 1149 return true; |
| 1147 | 1150 |
| 1148 #else | 1151 #else |
| 1149 return false; | 1152 return false; |
| 1150 #endif | 1153 #endif |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 } | 1191 } |
| 1189 // Otherwise, if the sliding state window computation has not been | 1192 // Otherwise, if the sliding state window computation has not been |
| 1190 // started we do it now. | 1193 // started we do it now. |
| 1191 if (sliding_state_window_ == NULL) { | 1194 if (sliding_state_window_ == NULL) { |
| 1192 sliding_state_window_ = new SlidingStateWindow(); | 1195 sliding_state_window_ = new SlidingStateWindow(); |
| 1193 } | 1196 } |
| 1194 #endif | 1197 #endif |
| 1195 } | 1198 } |
| 1196 | 1199 |
| 1197 | 1200 |
| 1198 // | |
| 1199 // VMState class implementation. A simple stack of VM states held by the | |
| 1200 // logger and partially threaded through the call stack. States are pushed by | |
| 1201 // VMState construction and popped by destruction. | |
| 1202 // | |
| 1203 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 1204 static const char* StateToString(StateTag state) { | |
| 1205 switch (state) { | |
| 1206 case JS: | |
| 1207 return "JS"; | |
| 1208 case GC: | |
| 1209 return "GC"; | |
| 1210 case COMPILER: | |
| 1211 return "COMPILER"; | |
| 1212 case OTHER: | |
| 1213 return "OTHER"; | |
| 1214 default: | |
| 1215 UNREACHABLE(); | |
| 1216 return NULL; | |
| 1217 } | |
| 1218 } | |
| 1219 | |
| 1220 VMState::VMState(StateTag state) { | |
| 1221 #if !defined(ENABLE_HEAP_PROTECTION) | |
| 1222 // When not protecting the heap, there is no difference between | |
| 1223 // EXTERNAL and OTHER. As an optimization in that case, we will not | |
| 1224 // perform EXTERNAL->OTHER transitions through the API. We thus | |
| 1225 // compress the two states into one. | |
| 1226 if (state == EXTERNAL) state = OTHER; | |
| 1227 #endif | |
| 1228 state_ = state; | |
| 1229 previous_ = Logger::current_state_; | |
| 1230 Logger::current_state_ = this; | |
| 1231 | |
| 1232 if (FLAG_log_state_changes) { | |
| 1233 LOG(UncheckedStringEvent("Entering", StateToString(state_))); | |
| 1234 if (previous_ != NULL) { | |
| 1235 LOG(UncheckedStringEvent("From", StateToString(previous_->state_))); | |
| 1236 } | |
| 1237 } | |
| 1238 | |
| 1239 #ifdef ENABLE_HEAP_PROTECTION | |
| 1240 if (FLAG_protect_heap && previous_ != NULL) { | |
| 1241 if (state_ == EXTERNAL) { | |
| 1242 // We are leaving V8. | |
| 1243 ASSERT(previous_->state_ != EXTERNAL); | |
| 1244 Heap::Protect(); | |
| 1245 } else if (previous_->state_ == EXTERNAL) { | |
| 1246 // We are entering V8. | |
| 1247 Heap::Unprotect(); | |
| 1248 } | |
| 1249 } | |
| 1250 #endif | |
| 1251 } | |
| 1252 | |
| 1253 | |
| 1254 VMState::~VMState() { | |
| 1255 Logger::current_state_ = previous_; | |
| 1256 | |
| 1257 if (FLAG_log_state_changes) { | |
| 1258 LOG(UncheckedStringEvent("Leaving", StateToString(state_))); | |
| 1259 if (previous_ != NULL) { | |
| 1260 LOG(UncheckedStringEvent("To", StateToString(previous_->state_))); | |
| 1261 } | |
| 1262 } | |
| 1263 | |
| 1264 #ifdef ENABLE_HEAP_PROTECTION | |
| 1265 if (FLAG_protect_heap && previous_ != NULL) { | |
| 1266 if (state_ == EXTERNAL) { | |
| 1267 // We are reentering V8. | |
| 1268 ASSERT(previous_->state_ != EXTERNAL); | |
| 1269 Heap::Unprotect(); | |
| 1270 } else if (previous_->state_ == EXTERNAL) { | |
| 1271 // We are leaving V8. | |
| 1272 Heap::Protect(); | |
| 1273 } | |
| 1274 } | |
| 1275 #endif | |
| 1276 } | |
| 1277 #endif | |
| 1278 | |
| 1279 } } // namespace v8::internal | 1201 } } // namespace v8::internal |
| OLD | NEW |