blob: 278cff1fc8ba93293953f0cf911c5821d8564c6f [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2009 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/log-utils.h"
8#include "src/string-stream.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009#include "src/version.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000010
11namespace v8 {
12namespace internal {
13
Steve Blocka7e24c12009-10-30 11:49:00 +000014
Ben Murdoch69a99ed2011-11-30 16:03:39 +000015const char* const Log::kLogToTemporaryFile = "&";
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016const char* const Log::kLogToConsole = "-";
Steve Blocka7e24c12009-10-30 11:49:00 +000017
18
Steve Block44f0eee2011-05-26 01:26:41 +010019Log::Log(Logger* logger)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000020 : is_stopped_(false),
Steve Block44f0eee2011-05-26 01:26:41 +010021 output_handle_(NULL),
Steve Block44f0eee2011-05-26 01:26:41 +010022 message_buffer_(NULL),
23 logger_(logger) {
24}
Steve Blocka7e24c12009-10-30 11:49:00 +000025
26
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027void Log::Initialize(const char* log_file_name) {
Steve Blocka7e24c12009-10-30 11:49:00 +000028 message_buffer_ = NewArray<char>(kMessageBufferSize);
Steve Block44f0eee2011-05-26 01:26:41 +010029
30 // --log-all enables all the log flags.
31 if (FLAG_log_all) {
Steve Block44f0eee2011-05-26 01:26:41 +010032 FLAG_log_api = true;
33 FLAG_log_code = true;
34 FLAG_log_gc = true;
35 FLAG_log_suspect = true;
36 FLAG_log_handles = true;
37 FLAG_log_regexp = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 FLAG_log_internal_timer_events = true;
Steve Block44f0eee2011-05-26 01:26:41 +010039 }
40
41 // --prof implies --log-code.
42 if (FLAG_prof) FLAG_log_code = true;
43
Steve Block44f0eee2011-05-26 01:26:41 +010044 // If we're logging anything, we need to open the log file.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 if (Log::InitLogAtStart()) {
46 if (strcmp(log_file_name, kLogToConsole) == 0) {
Steve Block44f0eee2011-05-26 01:26:41 +010047 OpenStdout();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000049 OpenTemporaryFile();
50 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 OpenFile(log_file_name);
Steve Block44f0eee2011-05-26 01:26:41 +010052 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040053
54 if (output_handle_ != nullptr) {
55 Log::MessageBuilder msg(this);
56 msg.Append("v8-version,%d,%d,%d,%d,%d", Version::GetMajor(),
57 Version::GetMinor(), Version::GetBuild(), Version::GetPatch(),
58 Version::IsCandidate());
59 msg.WriteToLogFile();
60 }
Steve Block44f0eee2011-05-26 01:26:41 +010061 }
Steve Blocka7e24c12009-10-30 11:49:00 +000062}
63
64
65void Log::OpenStdout() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 DCHECK(!IsEnabled());
Steve Blocka7e24c12009-10-30 11:49:00 +000067 output_handle_ = stdout;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000068}
69
70
71void Log::OpenTemporaryFile() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 DCHECK(!IsEnabled());
73 output_handle_ = base::OS::OpenTemporaryFile();
Steve Blocka7e24c12009-10-30 11:49:00 +000074}
75
76
77void Log::OpenFile(const char* name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 DCHECK(!IsEnabled());
79 output_handle_ = base::OS::FOpen(name, base::OS::LogFileOpenMode);
Steve Blocka7e24c12009-10-30 11:49:00 +000080}
81
82
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000083FILE* Log::Close() {
84 FILE* result = NULL;
85 if (output_handle_ != NULL) {
86 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
87 fclose(output_handle_);
88 } else {
89 result = output_handle_;
90 }
Steve Blocka7e24c12009-10-30 11:49:00 +000091 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000092 output_handle_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +000093
94 DeleteArray(message_buffer_);
95 message_buffer_ = NULL;
96
Steve Blocka7e24c12009-10-30 11:49:00 +000097 is_stopped_ = false;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000098 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +000099}
100
101
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102Log::MessageBuilder::MessageBuilder(Log* log)
103 : log_(log),
104 lock_guard_(&log_->mutex_),
Steve Block44f0eee2011-05-26 01:26:41 +0100105 pos_(0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 DCHECK(log_->message_buffer_ != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000107}
108
109
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110void Log::MessageBuilder::Append(const char* format, ...) {
Steve Block44f0eee2011-05-26 01:26:41 +0100111 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000112 Log::kMessageBufferSize - pos_);
113 va_list args;
114 va_start(args, format);
115 AppendVA(format, args);
116 va_end(args);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000118}
119
120
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121void Log::MessageBuilder::AppendVA(const char* format, va_list args) {
Steve Block44f0eee2011-05-26 01:26:41 +0100122 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000123 Log::kMessageBufferSize - pos_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 int result = v8::internal::VSNPrintF(buf, format, args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000125
126 // Result is -1 if output was truncated.
127 if (result >= 0) {
128 pos_ += result;
129 } else {
130 pos_ = Log::kMessageBufferSize;
131 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000133}
134
135
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136void Log::MessageBuilder::Append(const char c) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000137 if (pos_ < Log::kMessageBufferSize) {
Steve Block44f0eee2011-05-26 01:26:41 +0100138 log_->message_buffer_[pos_++] = c;
Steve Blocka7e24c12009-10-30 11:49:00 +0000139 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000141}
142
143
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144void Log::MessageBuilder::AppendDoubleQuotedString(const char* string) {
145 Append('"');
146 for (const char* p = string; *p != '\0'; p++) {
147 if (*p == '"') {
148 Append('\\');
149 }
150 Append(*p);
151 }
152 Append('"');
153}
154
155
156void Log::MessageBuilder::Append(String* str) {
157 DisallowHeapAllocation no_gc; // Ensure string stay valid.
Steve Blocka7e24c12009-10-30 11:49:00 +0000158 int length = str->length();
159 for (int i = 0; i < length; i++) {
160 Append(static_cast<char>(str->Get(i)));
161 }
162}
163
164
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165void Log::MessageBuilder::AppendAddress(Address addr) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100166 Append("0x%" V8PRIxPTR, addr);
Steve Blocka7e24c12009-10-30 11:49:00 +0000167}
168
169
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170void Log::MessageBuilder::AppendSymbolName(Symbol* symbol) {
171 DCHECK(symbol);
172 Append("symbol(");
173 if (!symbol->name()->IsUndefined()) {
174 Append("\"");
175 AppendDetailed(String::cast(symbol->name()), false);
176 Append("\" ");
177 }
178 Append("hash %x)", symbol->Hash());
179}
180
181
182void Log::MessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000183 if (str == NULL) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 DisallowHeapAllocation no_gc; // Ensure string stay valid.
Steve Blocka7e24c12009-10-30 11:49:00 +0000185 int len = str->length();
186 if (len > 0x1000)
187 len = 0x1000;
188 if (show_impl_info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 Append(str->IsOneByteRepresentation() ? 'a' : '2');
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 if (StringShape(str).IsExternal())
191 Append('e');
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 if (StringShape(str).IsInternalized())
Steve Blocka7e24c12009-10-30 11:49:00 +0000193 Append('#');
194 Append(":%i:", str->length());
195 }
196 for (int i = 0; i < len; i++) {
197 uc32 c = str->Get(i);
198 if (c > 0xff) {
199 Append("\\u%04x", c);
200 } else if (c < 32 || c > 126) {
201 Append("\\x%02x", c);
202 } else if (c == ',') {
203 Append("\\,");
204 } else if (c == '\\') {
205 Append("\\\\");
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100206 } else if (c == '\"') {
207 Append("\"\"");
Steve Blocka7e24c12009-10-30 11:49:00 +0000208 } else {
209 Append("%lc", c);
210 }
211 }
212}
213
214
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215void Log::MessageBuilder::AppendStringPart(const char* str, int len) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 if (pos_ + len > Log::kMessageBufferSize) {
217 len = Log::kMessageBufferSize - pos_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 DCHECK(len >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000219 if (len == 0) return;
220 }
Steve Block44f0eee2011-05-26 01:26:41 +0100221 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000222 Log::kMessageBufferSize - pos_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 StrNCpy(buf, str, len);
Steve Blocka7e24c12009-10-30 11:49:00 +0000224 pos_ += len;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000226}
227
228
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000229void Log::MessageBuilder::WriteToLogFile() {
230 DCHECK(pos_ <= Log::kMessageBufferSize);
231 // Assert that we do not already have a new line at the end.
232 DCHECK(pos_ == 0 || log_->message_buffer_[pos_ - 1] != '\n');
233 if (pos_ == Log::kMessageBufferSize) pos_--;
234 log_->message_buffer_[pos_++] = '\n';
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000235 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
Steve Block44f0eee2011-05-26 01:26:41 +0100236 if (written != pos_) {
237 log_->stop();
238 log_->logger_->LogFailure();
Steve Blocka7e24c12009-10-30 11:49:00 +0000239 }
240}
241
Steve Block44f0eee2011-05-26 01:26:41 +0100242
Steve Blocka7e24c12009-10-30 11:49:00 +0000243} } // namespace v8::internal