| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 Logger::Logger() | 324 Logger::Logger() |
| 325 : ticker_(NULL), | 325 : ticker_(NULL), |
| 326 profiler_(NULL), | 326 profiler_(NULL), |
| 327 sliding_state_window_(NULL), | 327 sliding_state_window_(NULL), |
| 328 log_events_(NULL), | 328 log_events_(NULL), |
| 329 compression_helper_(NULL), | 329 compression_helper_(NULL), |
| 330 logging_nesting_(0), | 330 logging_nesting_(0), |
| 331 cpu_profiler_nesting_(0), | 331 cpu_profiler_nesting_(0), |
| 332 heap_profiler_nesting_(0), | 332 heap_profiler_nesting_(0), |
| 333 log_(new Log(this)), | 333 log_(new Log(this)), |
| 334 is_initialized_(false) { | 334 is_initialized_(false), |
| 335 last_address_(NULL), |
| 336 prev_sp_(NULL), |
| 337 prev_function_(NULL), |
| 338 prev_to_(NULL), |
| 339 prev_code_(NULL) { |
| 335 } | 340 } |
| 336 | 341 |
| 337 #define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name, | 342 #define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name, |
| 338 const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 343 const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| 339 LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT) | 344 LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT) |
| 340 }; | 345 }; |
| 341 #undef DECLARE_LONG_EVENT | 346 #undef DECLARE_LONG_EVENT |
| 342 | 347 |
| 343 #define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name, | 348 #define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name, |
| 344 const char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 349 const char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 if (!compression_helper_->HandleMessage(&msg)) return; | 880 if (!compression_helper_->HandleMessage(&msg)) return; |
| 876 } | 881 } |
| 877 msg.Append('\n'); | 882 msg.Append('\n'); |
| 878 msg.WriteToLogFile(); | 883 msg.WriteToLogFile(); |
| 879 #endif | 884 #endif |
| 880 } | 885 } |
| 881 | 886 |
| 882 | 887 |
| 883 void Logger::FunctionCreateEvent(JSFunction* function) { | 888 void Logger::FunctionCreateEvent(JSFunction* function) { |
| 884 #ifdef ENABLE_LOGGING_AND_PROFILING | 889 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 885 static Address prev_code = NULL; | |
| 886 if (!log_->IsEnabled() || !FLAG_log_code) return; | 890 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 887 LogMessageBuilder msg(this); | 891 LogMessageBuilder msg(this); |
| 888 msg.Append("%s,", log_events_[FUNCTION_CREATION_EVENT]); | 892 msg.Append("%s,", log_events_[FUNCTION_CREATION_EVENT]); |
| 889 msg.AppendAddress(function->address()); | 893 msg.AppendAddress(function->address()); |
| 890 msg.Append(','); | 894 msg.Append(','); |
| 891 msg.AppendAddress(function->code()->address(), prev_code); | 895 msg.AppendAddress(function->code()->address(), prev_code_); |
| 892 prev_code = function->code()->address(); | 896 prev_code_ = function->code()->address(); |
| 893 if (FLAG_compress_log) { | 897 if (FLAG_compress_log) { |
| 894 ASSERT(compression_helper_ != NULL); | 898 ASSERT(compression_helper_ != NULL); |
| 895 if (!compression_helper_->HandleMessage(&msg)) return; | 899 if (!compression_helper_->HandleMessage(&msg)) return; |
| 896 } | 900 } |
| 897 msg.Append('\n'); | 901 msg.Append('\n'); |
| 898 msg.WriteToLogFile(); | 902 msg.WriteToLogFile(); |
| 899 #endif | 903 #endif |
| 900 } | 904 } |
| 901 | 905 |
| 902 | 906 |
| 903 void Logger::FunctionMoveEvent(Address from, Address to) { | 907 void Logger::FunctionMoveEvent(Address from, Address to) { |
| 904 #ifdef ENABLE_LOGGING_AND_PROFILING | 908 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 905 MoveEventInternal(FUNCTION_MOVE_EVENT, from, to); | 909 MoveEventInternal(FUNCTION_MOVE_EVENT, from, to); |
| 906 #endif | 910 #endif |
| 907 } | 911 } |
| 908 | 912 |
| 909 | 913 |
| 910 void Logger::FunctionDeleteEvent(Address from) { | 914 void Logger::FunctionDeleteEvent(Address from) { |
| 911 #ifdef ENABLE_LOGGING_AND_PROFILING | 915 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 912 DeleteEventInternal(FUNCTION_DELETE_EVENT, from); | 916 DeleteEventInternal(FUNCTION_DELETE_EVENT, from); |
| 913 #endif | 917 #endif |
| 914 } | 918 } |
| 915 | 919 |
| 916 | 920 |
| 917 #ifdef ENABLE_LOGGING_AND_PROFILING | 921 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 918 void Logger::MoveEventInternal(LogEventsAndTags event, | 922 void Logger::MoveEventInternal(LogEventsAndTags event, |
| 919 Address from, | 923 Address from, |
| 920 Address to) { | 924 Address to) { |
| 921 static Address prev_to_ = NULL; | |
| 922 if (!log_->IsEnabled() || !FLAG_log_code) return; | 925 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 923 LogMessageBuilder msg(this); | 926 LogMessageBuilder msg(this); |
| 924 msg.Append("%s,", log_events_[event]); | 927 msg.Append("%s,", log_events_[event]); |
| 925 msg.AppendAddress(from); | 928 msg.AppendAddress(from); |
| 926 msg.Append(','); | 929 msg.Append(','); |
| 927 msg.AppendAddress(to, prev_to_); | 930 msg.AppendAddress(to, prev_to_); |
| 928 prev_to_ = to; | 931 prev_to_ = to; |
| 929 if (FLAG_compress_log) { | 932 if (FLAG_compress_log) { |
| 930 ASSERT(compression_helper_ != NULL); | 933 ASSERT(compression_helper_ != NULL); |
| 931 if (!compression_helper_->HandleMessage(&msg)) return; | 934 if (!compression_helper_->HandleMessage(&msg)) return; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 void Logger::HeapSampleJSConstructorEvent(const char* constructor, | 1040 void Logger::HeapSampleJSConstructorEvent(const char* constructor, |
| 1038 int number, int bytes) { | 1041 int number, int bytes) { |
| 1039 #ifdef ENABLE_LOGGING_AND_PROFILING | 1042 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1040 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1043 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
| 1041 LogMessageBuilder msg(this); | 1044 LogMessageBuilder msg(this); |
| 1042 msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes); | 1045 msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes); |
| 1043 msg.WriteToLogFile(); | 1046 msg.WriteToLogFile(); |
| 1044 #endif | 1047 #endif |
| 1045 } | 1048 } |
| 1046 | 1049 |
| 1050 // Event starts with comma, so we don't have it in the format string. |
| 1051 static const char kEventText[] = "heap-js-ret-item,%s"; |
| 1052 // We take placeholder strings into account, but it's OK to be conservative. |
| 1053 static const int kEventTextLen = sizeof(kEventText)/sizeof(kEventText[0]); |
| 1047 | 1054 |
| 1048 void Logger::HeapSampleJSRetainersEvent( | 1055 void Logger::HeapSampleJSRetainersEvent( |
| 1049 const char* constructor, const char* event) { | 1056 const char* constructor, const char* event) { |
| 1050 #ifdef ENABLE_LOGGING_AND_PROFILING | 1057 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1051 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1058 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
| 1052 // Event starts with comma, so we don't have it in the format string. | |
| 1053 static const char* event_text = "heap-js-ret-item,%s"; | |
| 1054 // We take placeholder strings into account, but it's OK to be conservative. | |
| 1055 static const int event_text_len = StrLength(event_text); | |
| 1056 const int cons_len = StrLength(constructor); | 1059 const int cons_len = StrLength(constructor); |
| 1057 const int event_len = StrLength(event); | 1060 const int event_len = StrLength(event); |
| 1058 int pos = 0; | 1061 int pos = 0; |
| 1059 // Retainer lists can be long. We may need to split them into multiple events. | 1062 // Retainer lists can be long. We may need to split them into multiple events. |
| 1060 do { | 1063 do { |
| 1061 LogMessageBuilder msg(this); | 1064 LogMessageBuilder msg(this); |
| 1062 msg.Append(event_text, constructor); | 1065 msg.Append(kEventText, constructor); |
| 1063 int to_write = event_len - pos; | 1066 int to_write = event_len - pos; |
| 1064 if (to_write > Log::kMessageBufferSize - (cons_len + event_text_len)) { | 1067 if (to_write > Log::kMessageBufferSize - (cons_len + kEventTextLen)) { |
| 1065 int cut_pos = pos + Log::kMessageBufferSize - (cons_len + event_text_len); | 1068 int cut_pos = pos + Log::kMessageBufferSize - (cons_len + kEventTextLen); |
| 1066 ASSERT(cut_pos < event_len); | 1069 ASSERT(cut_pos < event_len); |
| 1067 while (cut_pos > pos && event[cut_pos] != ',') --cut_pos; | 1070 while (cut_pos > pos && event[cut_pos] != ',') --cut_pos; |
| 1068 if (event[cut_pos] != ',') { | 1071 if (event[cut_pos] != ',') { |
| 1069 // Crash in debug mode, skip in release mode. | 1072 // Crash in debug mode, skip in release mode. |
| 1070 ASSERT(false); | 1073 ASSERT(false); |
| 1071 return; | 1074 return; |
| 1072 } | 1075 } |
| 1073 // Append a piece of event that fits, without trailing comma. | 1076 // Append a piece of event that fits, without trailing comma. |
| 1074 msg.AppendStringPart(event + pos, cut_pos - pos); | 1077 msg.AppendStringPart(event + pos, cut_pos - pos); |
| 1075 // Start next piece with comma. | 1078 // Start next piece with comma. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 parameter_string); | 1128 parameter_string); |
| 1126 DeleteArray(parameter_string); | 1129 DeleteArray(parameter_string); |
| 1127 msg.WriteToLogFile(); | 1130 msg.WriteToLogFile(); |
| 1128 #endif | 1131 #endif |
| 1129 } | 1132 } |
| 1130 | 1133 |
| 1131 | 1134 |
| 1132 #ifdef ENABLE_LOGGING_AND_PROFILING | 1135 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1133 void Logger::TickEvent(TickSample* sample, bool overflow) { | 1136 void Logger::TickEvent(TickSample* sample, bool overflow) { |
| 1134 if (!log_->IsEnabled() || !FLAG_prof) return; | 1137 if (!log_->IsEnabled() || !FLAG_prof) return; |
| 1135 static Address prev_sp = NULL; | |
| 1136 static Address prev_function = NULL; | |
| 1137 LogMessageBuilder msg(this); | 1138 LogMessageBuilder msg(this); |
| 1138 msg.Append("%s,", log_events_[TICK_EVENT]); | 1139 msg.Append("%s,", log_events_[TICK_EVENT]); |
| 1139 Address prev_addr = sample->pc; | 1140 Address prev_addr = sample->pc; |
| 1140 msg.AppendAddress(prev_addr); | 1141 msg.AppendAddress(prev_addr); |
| 1141 msg.Append(','); | 1142 msg.Append(','); |
| 1142 msg.AppendAddress(sample->sp, prev_sp); | 1143 msg.AppendAddress(sample->sp, prev_sp_); |
| 1143 prev_sp = sample->sp; | 1144 prev_sp_ = sample->sp; |
| 1144 msg.Append(','); | 1145 msg.Append(','); |
| 1145 msg.AppendAddress(sample->function, prev_function); | 1146 msg.AppendAddress(sample->function, prev_function_); |
| 1146 prev_function = sample->function; | 1147 prev_function_ = sample->function; |
| 1147 msg.Append(",%d", static_cast<int>(sample->state)); | 1148 msg.Append(",%d", static_cast<int>(sample->state)); |
| 1148 if (overflow) { | 1149 if (overflow) { |
| 1149 msg.Append(",overflow"); | 1150 msg.Append(",overflow"); |
| 1150 } | 1151 } |
| 1151 for (int i = 0; i < sample->frames_count; ++i) { | 1152 for (int i = 0; i < sample->frames_count; ++i) { |
| 1152 msg.Append(','); | 1153 msg.Append(','); |
| 1153 msg.AppendAddress(sample->stack[i], prev_addr); | 1154 msg.AppendAddress(sample->stack[i], prev_addr); |
| 1154 prev_addr = sample->stack[i]; | 1155 prev_addr = sample->stack[i]; |
| 1155 } | 1156 } |
| 1156 if (FLAG_compress_log) { | 1157 if (FLAG_compress_log) { |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 } | 1502 } |
| 1502 // Otherwise, if the sliding state window computation has not been | 1503 // Otherwise, if the sliding state window computation has not been |
| 1503 // started we do it now. | 1504 // started we do it now. |
| 1504 if (sliding_state_window_ == NULL) { | 1505 if (sliding_state_window_ == NULL) { |
| 1505 sliding_state_window_ = new SlidingStateWindow(); | 1506 sliding_state_window_ = new SlidingStateWindow(); |
| 1506 } | 1507 } |
| 1507 #endif | 1508 #endif |
| 1508 } | 1509 } |
| 1509 | 1510 |
| 1510 } } // namespace v8::internal | 1511 } } // namespace v8::internal |
| OLD | NEW |