blob: d8d8f5934f72e65a0cc6e9ed2a4c76d5269923c9 [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 mutex_(NULL),
45 message_buffer_(NULL),
46 logger_(logger) {
47}
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000048
49
jkummerow@chromium.org10480472013-07-17 08:22:15 +000050void Log::Initialize(const char* log_file_name) {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000051 mutex_ = OS::CreateMutex();
52 message_buffer_ = NewArray<char>(kMessageBufferSize);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000053
54 // --log-all enables all the log flags.
55 if (FLAG_log_all) {
56 FLAG_log_runtime = true;
57 FLAG_log_api = true;
58 FLAG_log_code = true;
59 FLAG_log_gc = true;
60 FLAG_log_suspect = true;
61 FLAG_log_handles = true;
62 FLAG_log_regexp = true;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +000063 FLAG_log_internal_timer_events = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000064 }
65
66 // --prof implies --log-code.
67 if (FLAG_prof) FLAG_log_code = true;
68
69 // --prof_lazy controls --log-code, implies --noprof_auto.
70 if (FLAG_prof_lazy) {
71 FLAG_log_code = false;
72 FLAG_prof_auto = false;
73 }
74
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 // If we're logging anything, we need to open the log file.
danno@chromium.orgca29dd82013-04-26 11:59:48 +000076 if (Log::InitLogAtStart()) {
jkummerow@chromium.org10480472013-07-17 08:22:15 +000077 if (strcmp(log_file_name, kLogToConsole) == 0) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000078 OpenStdout();
jkummerow@chromium.org10480472013-07-17 08:22:15 +000079 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) {
whesse@chromium.org030d38e2011-07-13 13:23:34 +000080 OpenTemporaryFile();
81 } else {
jkummerow@chromium.org10480472013-07-17 08:22:15 +000082 OpenFile(log_file_name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000083 }
84 }
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000085}
86
87
88void Log::OpenStdout() {
89 ASSERT(!IsEnabled());
90 output_handle_ = stdout;
whesse@chromium.org030d38e2011-07-13 13:23:34 +000091}
92
93
94void Log::OpenTemporaryFile() {
95 ASSERT(!IsEnabled());
96 output_handle_ = i::OS::OpenTemporaryFile();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +000097}
98
99
100void Log::OpenFile(const char* name) {
101 ASSERT(!IsEnabled());
102 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000103}
104
105
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000106FILE* Log::Close() {
107 FILE* result = NULL;
108 if (output_handle_ != NULL) {
109 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
110 fclose(output_handle_);
111 } else {
112 result = output_handle_;
113 }
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000114 }
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000115 output_handle_ = NULL;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000116
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000117 DeleteArray(message_buffer_);
118 message_buffer_ = NULL;
119
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000120 delete mutex_;
121 mutex_ = NULL;
122
123 is_stopped_ = false;
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000124 return result;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000125}
126
127
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000128Log::MessageBuilder::MessageBuilder(Log* log)
129 : log_(log),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000130 sl(log_->mutex_),
131 pos_(0) {
132 ASSERT(log_->message_buffer_ != NULL);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000133}
134
135
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000136void Log::MessageBuilder::Append(const char* format, ...) {
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 va_list args;
140 va_start(args, format);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000141 AppendVA(format, args);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000142 va_end(args);
143 ASSERT(pos_ <= Log::kMessageBufferSize);
144}
145
146
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000147void Log::MessageBuilder::AppendVA(const char* format, va_list args) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000148 Vector<char> buf(log_->message_buffer_ + pos_,
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000149 Log::kMessageBufferSize - pos_);
150 int result = v8::internal::OS::VSNPrintF(buf, format, args);
151
152 // Result is -1 if output was truncated.
153 if (result >= 0) {
154 pos_ += result;
155 } else {
156 pos_ = Log::kMessageBufferSize;
157 }
158 ASSERT(pos_ <= Log::kMessageBufferSize);
159}
160
161
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000162void Log::MessageBuilder::Append(const char c) {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000163 if (pos_ < Log::kMessageBufferSize) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000164 log_->message_buffer_[pos_++] = c;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000165 }
166 ASSERT(pos_ <= Log::kMessageBufferSize);
167}
168
169
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000170void Log::MessageBuilder::AppendDoubleQuotedString(const char* string) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000171 Append('"');
172 for (const char* p = string; *p != '\0'; p++) {
173 if (*p == '"') {
174 Append('\\');
175 }
176 Append(*p);
177 }
178 Append('"');
179}
180
181
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000182void Log::MessageBuilder::Append(String* str) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000183 DisallowHeapAllocation no_gc; // Ensure string stay valid.
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000184 int length = str->length();
185 for (int i = 0; i < length; i++) {
186 Append(static_cast<char>(str->Get(i)));
187 }
188}
189
190
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000191void Log::MessageBuilder::AppendAddress(Address addr) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000192 Append("0x%" V8PRIxPTR, addr);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000193}
194
195
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000196void Log::MessageBuilder::AppendSymbolName(Symbol* symbol) {
197 ASSERT(symbol);
198 Append("symbol(");
199 if (!symbol->name()->IsUndefined()) {
200 Append("\"");
201 AppendDetailed(String::cast(symbol->name()), false);
202 Append("\" ");
203 }
204 Append("hash %x)", symbol->Hash());
205}
206
207
208void Log::MessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000209 if (str == NULL) return;
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000210 DisallowHeapAllocation no_gc; // Ensure string stay valid.
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000211 int len = str->length();
212 if (len > 0x1000)
213 len = 0x1000;
214 if (show_impl_info) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000215 Append(str->IsOneByteRepresentation() ? 'a' : '2');
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000216 if (StringShape(str).IsExternal())
217 Append('e');
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000218 if (StringShape(str).IsInternalized())
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000219 Append('#');
220 Append(":%i:", str->length());
221 }
222 for (int i = 0; i < len; i++) {
223 uc32 c = str->Get(i);
224 if (c > 0xff) {
225 Append("\\u%04x", c);
226 } else if (c < 32 || c > 126) {
227 Append("\\x%02x", c);
228 } else if (c == ',') {
229 Append("\\,");
230 } else if (c == '\\') {
231 Append("\\\\");
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000232 } else if (c == '\"') {
233 Append("\"\"");
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000234 } else {
235 Append("%lc", c);
236 }
237 }
238}
239
240
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000241void Log::MessageBuilder::AppendStringPart(const char* str, int len) {
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000242 if (pos_ + len > Log::kMessageBufferSize) {
243 len = Log::kMessageBufferSize - pos_;
244 ASSERT(len >= 0);
245 if (len == 0) return;
246 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000247 Vector<char> buf(log_->message_buffer_ + pos_,
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000248 Log::kMessageBufferSize - pos_);
249 OS::StrNCpy(buf, str, len);
250 pos_ += len;
251 ASSERT(pos_ <= Log::kMessageBufferSize);
252}
253
254
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000255void Log::MessageBuilder::WriteToLogFile() {
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000256 ASSERT(pos_ <= Log::kMessageBufferSize);
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000257 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000258 if (written != pos_) {
259 log_->stop();
260 log_->logger_->LogFailure();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000261 }
262}
263
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000264
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000265} } // namespace v8::internal