blob: 909d4a513968ba6fc3007244d016116b89da0758 [file] [log] [blame]
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +00001// Copyright 2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
28#include "v8.h"
29
30#include "log-utils.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000031#include "string-stream.h"
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000032
33namespace v8 {
34namespace internal {
35
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000036
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000037const char* const Log::kLogToTemporaryFile = "&";
jkummerow@chromium.org10480472013-07-17 08:22:15 +000038const char* const Log::kLogToConsole = "-";
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000039
40
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000041Log::Log(Logger* logger)
whesse@chromium.org030d38e2011-07-13 13:23:34 +000042 : is_stopped_(false),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043 output_handle_(NULL),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000044 message_buffer_(NULL),
45 logger_(logger) {
46}
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000047
48
jkummerow@chromium.org10480472013-07-17 08:22:15 +000049void Log::Initialize(const char* log_file_name) {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000050 message_buffer_ = NewArray<char>(kMessageBufferSize);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000051
52 // --log-all enables all the log flags.
53 if (FLAG_log_all) {
54 FLAG_log_runtime = true;
55 FLAG_log_api = true;
56 FLAG_log_code = true;
57 FLAG_log_gc = true;
58 FLAG_log_suspect = true;
59 FLAG_log_handles = true;
60 FLAG_log_regexp = true;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +000061 FLAG_log_internal_timer_events = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000062 }
63
64 // --prof implies --log-code.
65 if (FLAG_prof) FLAG_log_code = true;
66
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000067 // If we're logging anything, we need to open the log file.
danno@chromium.orgca29dd82013-04-26 11:59:48 +000068 if (Log::InitLogAtStart()) {
jkummerow@chromium.org10480472013-07-17 08:22:15 +000069 if (strcmp(log_file_name, kLogToConsole) == 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000070 OpenStdout();
jkummerow@chromium.org10480472013-07-17 08:22:15 +000071 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) {
whesse@chromium.org030d38e2011-07-13 13:23:34 +000072 OpenTemporaryFile();
73 } else {
jkummerow@chromium.org10480472013-07-17 08:22:15 +000074 OpenFile(log_file_name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 }
76 }
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000077}
78
79
80void Log::OpenStdout() {
81 ASSERT(!IsEnabled());
82 output_handle_ = stdout;
whesse@chromium.org030d38e2011-07-13 13:23:34 +000083}
84
85
86void Log::OpenTemporaryFile() {
87 ASSERT(!IsEnabled());
88 output_handle_ = i::OS::OpenTemporaryFile();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000089}
90
91
92void Log::OpenFile(const char* name) {
93 ASSERT(!IsEnabled());
94 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000095}
96
97
whesse@chromium.org030d38e2011-07-13 13:23:34 +000098FILE* Log::Close() {
99 FILE* result = NULL;
100 if (output_handle_ != NULL) {
101 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
102 fclose(output_handle_);
103 } else {
104 result = output_handle_;
105 }
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000106 }
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000107 output_handle_ = NULL;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000108
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000109 DeleteArray(message_buffer_);
110 message_buffer_ = NULL;
111
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000112 is_stopped_ = false;
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000113 return result;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000114}
115
116
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000117Log::MessageBuilder::MessageBuilder(Log* log)
118 : log_(log),
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000119 lock_guard_(&log_->mutex_),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000120 pos_(0) {
121 ASSERT(log_->message_buffer_ != NULL);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000122}
123
124
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000125void Log::MessageBuilder::Append(const char* format, ...) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000126 Vector<char> buf(log_->message_buffer_ + pos_,
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000127 Log::kMessageBufferSize - pos_);
128 va_list args;
129 va_start(args, format);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000130 AppendVA(format, args);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000131 va_end(args);
132 ASSERT(pos_ <= Log::kMessageBufferSize);
133}
134
135
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000136void Log::MessageBuilder::AppendVA(const char* format, va_list args) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000137 Vector<char> buf(log_->message_buffer_ + pos_,
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000138 Log::kMessageBufferSize - pos_);
139 int result = v8::internal::OS::VSNPrintF(buf, format, args);
140
141 // Result is -1 if output was truncated.
142 if (result >= 0) {
143 pos_ += result;
144 } else {
145 pos_ = Log::kMessageBufferSize;
146 }
147 ASSERT(pos_ <= Log::kMessageBufferSize);
148}
149
150
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000151void Log::MessageBuilder::Append(const char c) {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000152 if (pos_ < Log::kMessageBufferSize) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000153 log_->message_buffer_[pos_++] = c;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000154 }
155 ASSERT(pos_ <= Log::kMessageBufferSize);
156}
157
158
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000159void Log::MessageBuilder::AppendDoubleQuotedString(const char* string) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000160 Append('"');
161 for (const char* p = string; *p != '\0'; p++) {
162 if (*p == '"') {
163 Append('\\');
164 }
165 Append(*p);
166 }
167 Append('"');
168}
169
170
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000171void Log::MessageBuilder::Append(String* str) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000172 DisallowHeapAllocation no_gc; // Ensure string stay valid.
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000173 int length = str->length();
174 for (int i = 0; i < length; i++) {
175 Append(static_cast<char>(str->Get(i)));
176 }
177}
178
179
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000180void Log::MessageBuilder::AppendAddress(Address addr) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000181 Append("0x%" V8PRIxPTR, addr);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000182}
183
184
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000185void Log::MessageBuilder::AppendSymbolName(Symbol* symbol) {
186 ASSERT(symbol);
187 Append("symbol(");
188 if (!symbol->name()->IsUndefined()) {
189 Append("\"");
190 AppendDetailed(String::cast(symbol->name()), false);
191 Append("\" ");
192 }
193 Append("hash %x)", symbol->Hash());
194}
195
196
197void Log::MessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000198 if (str == NULL) return;
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000199 DisallowHeapAllocation no_gc; // Ensure string stay valid.
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000200 int len = str->length();
201 if (len > 0x1000)
202 len = 0x1000;
203 if (show_impl_info) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000204 Append(str->IsOneByteRepresentation() ? 'a' : '2');
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000205 if (StringShape(str).IsExternal())
206 Append('e');
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000207 if (StringShape(str).IsInternalized())
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000208 Append('#');
209 Append(":%i:", str->length());
210 }
211 for (int i = 0; i < len; i++) {
212 uc32 c = str->Get(i);
213 if (c > 0xff) {
214 Append("\\u%04x", c);
215 } else if (c < 32 || c > 126) {
216 Append("\\x%02x", c);
217 } else if (c == ',') {
218 Append("\\,");
219 } else if (c == '\\') {
220 Append("\\\\");
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000221 } else if (c == '\"') {
222 Append("\"\"");
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000223 } else {
224 Append("%lc", c);
225 }
226 }
227}
228
229
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000230void Log::MessageBuilder::AppendStringPart(const char* str, int len) {
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000231 if (pos_ + len > Log::kMessageBufferSize) {
232 len = Log::kMessageBufferSize - pos_;
233 ASSERT(len >= 0);
234 if (len == 0) return;
235 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000236 Vector<char> buf(log_->message_buffer_ + pos_,
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000237 Log::kMessageBufferSize - pos_);
238 OS::StrNCpy(buf, str, len);
239 pos_ += len;
240 ASSERT(pos_ <= Log::kMessageBufferSize);
241}
242
243
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000244void Log::MessageBuilder::WriteToLogFile() {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000245 ASSERT(pos_ <= Log::kMessageBufferSize);
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000246 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000247 if (written != pos_) {
248 log_->stop();
249 log_->logger_->LogFailure();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000250 }
251}
252
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000253
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000254} } // namespace v8::internal