blob: a6fa6be42a1cfcc031b765146f99e1869b474a43 [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
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000128LogMessageBuilder::LogMessageBuilder(Logger* logger)
129 : log_(logger->log_),
130 sl(log_->mutex_),
131 pos_(0) {
132 ASSERT(log_->message_buffer_ != NULL);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000133}
134
135
136void LogMessageBuilder::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
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000147void LogMessageBuilder::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
162void LogMessageBuilder::Append(const char c) {
163 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
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000170void LogMessageBuilder::AppendDoubleQuotedString(const char* string) {
171 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
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000182void LogMessageBuilder::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
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000191void LogMessageBuilder::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
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000196void LogMessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000197 if (str == NULL) return;
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000198 DisallowHeapAllocation no_gc; // Ensure string stay valid.
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000199 int len = str->length();
200 if (len > 0x1000)
201 len = 0x1000;
202 if (show_impl_info) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000203 Append(str->IsOneByteRepresentation() ? 'a' : '2');
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000204 if (StringShape(str).IsExternal())
205 Append('e');
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000206 if (StringShape(str).IsInternalized())
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000207 Append('#');
208 Append(":%i:", str->length());
209 }
210 for (int i = 0; i < len; i++) {
211 uc32 c = str->Get(i);
212 if (c > 0xff) {
213 Append("\\u%04x", c);
214 } else if (c < 32 || c > 126) {
215 Append("\\x%02x", c);
216 } else if (c == ',') {
217 Append("\\,");
218 } else if (c == '\\') {
219 Append("\\\\");
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000220 } else if (c == '\"') {
221 Append("\"\"");
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000222 } else {
223 Append("%lc", c);
224 }
225 }
226}
227
228
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000229void LogMessageBuilder::AppendStringPart(const char* str, int len) {
230 if (pos_ + len > Log::kMessageBufferSize) {
231 len = Log::kMessageBufferSize - pos_;
232 ASSERT(len >= 0);
233 if (len == 0) return;
234 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000235 Vector<char> buf(log_->message_buffer_ + pos_,
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000236 Log::kMessageBufferSize - pos_);
237 OS::StrNCpy(buf, str, len);
238 pos_ += len;
239 ASSERT(pos_ <= Log::kMessageBufferSize);
240}
241
242
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000243void LogMessageBuilder::WriteToLogFile() {
244 ASSERT(pos_ <= Log::kMessageBufferSize);
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000245 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000246 if (written != pos_) {
247 log_->stop();
248 log_->logger_->LogFailure();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000249 }
250}
251
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000252
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000253} } // namespace v8::internal