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 |