| 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 17 matching lines...) Expand all Loading... |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "log-utils.h" | 30 #include "log-utils.h" |
| 31 #include "string-stream.h" | 31 #include "string-stream.h" |
| 32 | 32 |
| 33 namespace v8 { | 33 namespace v8 { |
| 34 namespace internal { | 34 namespace internal { |
| 35 | 35 |
| 36 | 36 |
| 37 const char* const Log::kLogToTemporaryFile = "&"; | 37 const char* const Log::kLogToTemporaryFile = "&"; |
| 38 const char* const Log::kLogToConsole = "-"; |
| 38 | 39 |
| 39 | 40 |
| 40 Log::Log(Logger* logger) | 41 Log::Log(Logger* logger) |
| 41 : is_stopped_(false), | 42 : is_stopped_(false), |
| 42 output_handle_(NULL), | 43 output_handle_(NULL), |
| 43 ll_output_handle_(NULL), | |
| 44 mutex_(NULL), | 44 mutex_(NULL), |
| 45 message_buffer_(NULL), | 45 message_buffer_(NULL), |
| 46 logger_(logger) { | 46 logger_(logger) { |
| 47 } | 47 } |
| 48 | 48 |
| 49 | 49 |
| 50 static void AddIsolateIdIfNeeded(StringStream* stream) { | 50 void Log::Initialize(const char* log_file_name) { |
| 51 Isolate* isolate = Isolate::Current(); | |
| 52 if (isolate->IsDefaultIsolate()) return; | |
| 53 stream->Add("isolate-%p-", isolate); | |
| 54 } | |
| 55 | |
| 56 | |
| 57 void Log::Initialize() { | |
| 58 mutex_ = OS::CreateMutex(); | 51 mutex_ = OS::CreateMutex(); |
| 59 message_buffer_ = NewArray<char>(kMessageBufferSize); | 52 message_buffer_ = NewArray<char>(kMessageBufferSize); |
| 60 | 53 |
| 61 // --log-all enables all the log flags. | 54 // --log-all enables all the log flags. |
| 62 if (FLAG_log_all) { | 55 if (FLAG_log_all) { |
| 63 FLAG_log_runtime = true; | 56 FLAG_log_runtime = true; |
| 64 FLAG_log_api = true; | 57 FLAG_log_api = true; |
| 65 FLAG_log_code = true; | 58 FLAG_log_code = true; |
| 66 FLAG_log_gc = true; | 59 FLAG_log_gc = true; |
| 67 FLAG_log_suspect = true; | 60 FLAG_log_suspect = true; |
| 68 FLAG_log_handles = true; | 61 FLAG_log_handles = true; |
| 69 FLAG_log_regexp = true; | 62 FLAG_log_regexp = true; |
| 70 FLAG_log_internal_timer_events = true; | 63 FLAG_log_internal_timer_events = true; |
| 71 } | 64 } |
| 72 | 65 |
| 73 // --prof implies --log-code. | 66 // --prof implies --log-code. |
| 74 if (FLAG_prof) FLAG_log_code = true; | 67 if (FLAG_prof) FLAG_log_code = true; |
| 75 | 68 |
| 76 // --prof_lazy controls --log-code, implies --noprof_auto. | 69 // --prof_lazy controls --log-code, implies --noprof_auto. |
| 77 if (FLAG_prof_lazy) { | 70 if (FLAG_prof_lazy) { |
| 78 FLAG_log_code = false; | 71 FLAG_log_code = false; |
| 79 FLAG_prof_auto = false; | 72 FLAG_prof_auto = false; |
| 80 } | 73 } |
| 81 | 74 |
| 82 // If we're logging anything, we need to open the log file. | 75 // If we're logging anything, we need to open the log file. |
| 83 if (Log::InitLogAtStart()) { | 76 if (Log::InitLogAtStart()) { |
| 84 if (strcmp(FLAG_logfile, "-") == 0) { | 77 if (strcmp(log_file_name, kLogToConsole) == 0) { |
| 85 OpenStdout(); | 78 OpenStdout(); |
| 86 } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) { | 79 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) { |
| 87 OpenTemporaryFile(); | 80 OpenTemporaryFile(); |
| 88 } else { | 81 } else { |
| 89 if (strchr(FLAG_logfile, '%') != NULL || | 82 OpenFile(log_file_name); |
| 90 !Isolate::Current()->IsDefaultIsolate()) { | |
| 91 // If there's a '%' in the log file name we have to expand | |
| 92 // placeholders. | |
| 93 HeapStringAllocator allocator; | |
| 94 StringStream stream(&allocator); | |
| 95 AddIsolateIdIfNeeded(&stream); | |
| 96 for (const char* p = FLAG_logfile; *p; p++) { | |
| 97 if (*p == '%') { | |
| 98 p++; | |
| 99 switch (*p) { | |
| 100 case '\0': | |
| 101 // If there's a % at the end of the string we back up | |
| 102 // one character so we can escape the loop properly. | |
| 103 p--; | |
| 104 break; | |
| 105 case 'p': | |
| 106 stream.Add("%d", OS::GetCurrentProcessId()); | |
| 107 break; | |
| 108 case 't': { | |
| 109 // %t expands to the current time in milliseconds. | |
| 110 double time = OS::TimeCurrentMillis(); | |
| 111 stream.Add("%.0f", FmtElm(time)); | |
| 112 break; | |
| 113 } | |
| 114 case '%': | |
| 115 // %% expands (contracts really) to %. | |
| 116 stream.Put('%'); | |
| 117 break; | |
| 118 default: | |
| 119 // All other %'s expand to themselves. | |
| 120 stream.Put('%'); | |
| 121 stream.Put(*p); | |
| 122 break; | |
| 123 } | |
| 124 } else { | |
| 125 stream.Put(*p); | |
| 126 } | |
| 127 } | |
| 128 SmartArrayPointer<const char> expanded = stream.ToCString(); | |
| 129 OpenFile(*expanded); | |
| 130 } else { | |
| 131 OpenFile(FLAG_logfile); | |
| 132 } | |
| 133 } | 83 } |
| 134 } | 84 } |
| 135 } | 85 } |
| 136 | 86 |
| 137 | 87 |
| 138 void Log::OpenStdout() { | 88 void Log::OpenStdout() { |
| 139 ASSERT(!IsEnabled()); | 89 ASSERT(!IsEnabled()); |
| 140 output_handle_ = stdout; | 90 output_handle_ = stdout; |
| 141 } | 91 } |
| 142 | 92 |
| 143 | 93 |
| 144 void Log::OpenTemporaryFile() { | 94 void Log::OpenTemporaryFile() { |
| 145 ASSERT(!IsEnabled()); | 95 ASSERT(!IsEnabled()); |
| 146 output_handle_ = i::OS::OpenTemporaryFile(); | 96 output_handle_ = i::OS::OpenTemporaryFile(); |
| 147 } | 97 } |
| 148 | 98 |
| 149 | 99 |
| 150 // Extension added to V8 log file name to get the low-level log name. | |
| 151 static const char kLowLevelLogExt[] = ".ll"; | |
| 152 | |
| 153 // File buffer size of the low-level log. We don't use the default to | |
| 154 // minimize the associated overhead. | |
| 155 static const int kLowLevelLogBufferSize = 2 * MB; | |
| 156 | |
| 157 | |
| 158 void Log::OpenFile(const char* name) { | 100 void Log::OpenFile(const char* name) { |
| 159 ASSERT(!IsEnabled()); | 101 ASSERT(!IsEnabled()); |
| 160 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); | 102 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); |
| 161 if (FLAG_ll_prof) { | |
| 162 // Open the low-level log file. | |
| 163 size_t len = strlen(name); | |
| 164 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt))); | |
| 165 OS::MemCopy(ll_name.start(), name, len); | |
| 166 OS::MemCopy(ll_name.start() + len, | |
| 167 kLowLevelLogExt, sizeof(kLowLevelLogExt)); | |
| 168 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); | |
| 169 setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize); | |
| 170 } | |
| 171 } | 103 } |
| 172 | 104 |
| 173 | 105 |
| 174 FILE* Log::Close() { | 106 FILE* Log::Close() { |
| 175 FILE* result = NULL; | 107 FILE* result = NULL; |
| 176 if (output_handle_ != NULL) { | 108 if (output_handle_ != NULL) { |
| 177 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) { | 109 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) { |
| 178 fclose(output_handle_); | 110 fclose(output_handle_); |
| 179 } else { | 111 } else { |
| 180 result = output_handle_; | 112 result = output_handle_; |
| 181 } | 113 } |
| 182 } | 114 } |
| 183 output_handle_ = NULL; | 115 output_handle_ = NULL; |
| 184 if (ll_output_handle_ != NULL) fclose(ll_output_handle_); | |
| 185 ll_output_handle_ = NULL; | |
| 186 | 116 |
| 187 DeleteArray(message_buffer_); | 117 DeleteArray(message_buffer_); |
| 188 message_buffer_ = NULL; | 118 message_buffer_ = NULL; |
| 189 | 119 |
| 190 delete mutex_; | 120 delete mutex_; |
| 191 mutex_ = NULL; | 121 mutex_ = NULL; |
| 192 | 122 |
| 193 is_stopped_ = false; | 123 is_stopped_ = false; |
| 194 return result; | 124 return result; |
| 195 } | 125 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 ASSERT(pos_ <= Log::kMessageBufferSize); | 244 ASSERT(pos_ <= Log::kMessageBufferSize); |
| 315 const int written = log_->WriteToFile(log_->message_buffer_, pos_); | 245 const int written = log_->WriteToFile(log_->message_buffer_, pos_); |
| 316 if (written != pos_) { | 246 if (written != pos_) { |
| 317 log_->stop(); | 247 log_->stop(); |
| 318 log_->logger_->LogFailure(); | 248 log_->logger_->LogFailure(); |
| 319 } | 249 } |
| 320 } | 250 } |
| 321 | 251 |
| 322 | 252 |
| 323 } } // namespace v8::internal | 253 } } // namespace v8::internal |
| OLD | NEW |