Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: src/log-utils.cc

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/log-utils.h ('k') | src/macros.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
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 #ifdef ENABLE_LOGGING_AND_PROFILING
37 36
38 LogDynamicBuffer::LogDynamicBuffer( 37 const char* Log::kLogToTemporaryFile = "&";
39 int block_size, int max_size, const char* seal, int seal_size)
40 : block_size_(block_size),
41 max_size_(max_size - (max_size % block_size_)),
42 seal_(seal),
43 seal_size_(seal_size),
44 blocks_(max_size_ / block_size_ + 1),
45 write_pos_(0), block_index_(0), block_write_pos_(0), is_sealed_(false) {
46 ASSERT(BlocksCount() > 0);
47 AllocateBlock(0);
48 for (int i = 1; i < BlocksCount(); ++i) {
49 blocks_[i] = NULL;
50 }
51 }
52 38
53 39
54 LogDynamicBuffer::~LogDynamicBuffer() {
55 for (int i = 0; i < BlocksCount(); ++i) {
56 DeleteArray(blocks_[i]);
57 }
58 }
59
60
61 int LogDynamicBuffer::Read(int from_pos, char* dest_buf, int buf_size) {
62 if (buf_size == 0) return 0;
63 int read_pos = from_pos;
64 int block_read_index = BlockIndex(from_pos);
65 int block_read_pos = PosInBlock(from_pos);
66 int dest_buf_pos = 0;
67 // Read until dest_buf is filled, or write_pos_ encountered.
68 while (read_pos < write_pos_ && dest_buf_pos < buf_size) {
69 const int read_size = Min(write_pos_ - read_pos,
70 Min(buf_size - dest_buf_pos, block_size_ - block_read_pos));
71 memcpy(dest_buf + dest_buf_pos,
72 blocks_[block_read_index] + block_read_pos, read_size);
73 block_read_pos += read_size;
74 dest_buf_pos += read_size;
75 read_pos += read_size;
76 if (block_read_pos == block_size_) {
77 block_read_pos = 0;
78 ++block_read_index;
79 }
80 }
81 return dest_buf_pos;
82 }
83
84
85 int LogDynamicBuffer::Seal() {
86 WriteInternal(seal_, seal_size_);
87 is_sealed_ = true;
88 return 0;
89 }
90
91
92 int LogDynamicBuffer::Write(const char* data, int data_size) {
93 if (is_sealed_) {
94 return 0;
95 }
96 if ((write_pos_ + data_size) <= (max_size_ - seal_size_)) {
97 return WriteInternal(data, data_size);
98 } else {
99 return Seal();
100 }
101 }
102
103
104 int LogDynamicBuffer::WriteInternal(const char* data, int data_size) {
105 int data_pos = 0;
106 while (data_pos < data_size) {
107 const int write_size =
108 Min(data_size - data_pos, block_size_ - block_write_pos_);
109 memcpy(blocks_[block_index_] + block_write_pos_, data + data_pos,
110 write_size);
111 block_write_pos_ += write_size;
112 data_pos += write_size;
113 if (block_write_pos_ == block_size_) {
114 block_write_pos_ = 0;
115 AllocateBlock(++block_index_);
116 }
117 }
118 write_pos_ += data_size;
119 return data_size;
120 }
121
122 // Must be the same message as in Logger::PauseProfiler.
123 const char* const Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
124
125 Log::Log(Logger* logger) 40 Log::Log(Logger* logger)
126 : write_to_file_(false), 41 : is_stopped_(false),
127 is_stopped_(false),
128 output_handle_(NULL), 42 output_handle_(NULL),
129 ll_output_handle_(NULL), 43 ll_output_handle_(NULL),
130 output_buffer_(NULL),
131 mutex_(NULL), 44 mutex_(NULL),
132 message_buffer_(NULL), 45 message_buffer_(NULL),
133 logger_(logger) { 46 logger_(logger) {
134 } 47 }
135 48
136 49
137 static void AddIsolateIdIfNeeded(StringStream* stream) { 50 static void AddIsolateIdIfNeeded(StringStream* stream) {
138 Isolate* isolate = Isolate::Current(); 51 Isolate* isolate = Isolate::Current();
139 if (isolate->IsDefaultIsolate()) return; 52 if (isolate->IsDefaultIsolate()) return;
140 stream->Add("isolate-%p-", isolate); 53 stream->Add("isolate-%p-", isolate);
141 } 54 }
142 55
143 56
144 void Log::Initialize() { 57 void Log::Initialize() {
145 #ifdef ENABLE_LOGGING_AND_PROFILING
146 mutex_ = OS::CreateMutex(); 58 mutex_ = OS::CreateMutex();
147 message_buffer_ = NewArray<char>(kMessageBufferSize); 59 message_buffer_ = NewArray<char>(kMessageBufferSize);
148 60
149 // --log-all enables all the log flags. 61 // --log-all enables all the log flags.
150 if (FLAG_log_all) { 62 if (FLAG_log_all) {
151 FLAG_log_runtime = true; 63 FLAG_log_runtime = true;
152 FLAG_log_api = true; 64 FLAG_log_api = true;
153 FLAG_log_code = true; 65 FLAG_log_code = true;
154 FLAG_log_gc = true; 66 FLAG_log_gc = true;
155 FLAG_log_suspect = true; 67 FLAG_log_suspect = true;
156 FLAG_log_handles = true; 68 FLAG_log_handles = true;
157 FLAG_log_regexp = true; 69 FLAG_log_regexp = true;
158 } 70 }
159 71
160 // --prof implies --log-code. 72 // --prof implies --log-code.
161 if (FLAG_prof) FLAG_log_code = true; 73 if (FLAG_prof) FLAG_log_code = true;
162 74
163 // --prof_lazy controls --log-code, implies --noprof_auto. 75 // --prof_lazy controls --log-code, implies --noprof_auto.
164 if (FLAG_prof_lazy) { 76 if (FLAG_prof_lazy) {
165 FLAG_log_code = false; 77 FLAG_log_code = false;
166 FLAG_prof_auto = false; 78 FLAG_prof_auto = false;
167 } 79 }
168 80
169 bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api 81 bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
170 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect 82 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
171 || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof; 83 || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
172 84
173 bool open_log_file = start_logging || FLAG_prof_lazy;
174
175 // If we're logging anything, we need to open the log file. 85 // If we're logging anything, we need to open the log file.
176 if (open_log_file) { 86 if (open_log_file) {
177 if (strcmp(FLAG_logfile, "-") == 0) { 87 if (strcmp(FLAG_logfile, "-") == 0) {
178 OpenStdout(); 88 OpenStdout();
179 } else if (strcmp(FLAG_logfile, "*") == 0) { 89 } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) {
180 OpenMemoryBuffer(); 90 OpenTemporaryFile();
181 } else { 91 } else {
182 if (strchr(FLAG_logfile, '%') != NULL || 92 if (strchr(FLAG_logfile, '%') != NULL ||
183 !Isolate::Current()->IsDefaultIsolate()) { 93 !Isolate::Current()->IsDefaultIsolate()) {
184 // If there's a '%' in the log file name we have to expand 94 // If there's a '%' in the log file name we have to expand
185 // placeholders. 95 // placeholders.
186 HeapStringAllocator allocator; 96 HeapStringAllocator allocator;
187 StringStream stream(&allocator); 97 StringStream stream(&allocator);
188 AddIsolateIdIfNeeded(&stream); 98 AddIsolateIdIfNeeded(&stream);
189 for (const char* p = FLAG_logfile; *p; p++) { 99 for (const char* p = FLAG_logfile; *p; p++) {
190 if (*p == '%') { 100 if (*p == '%') {
191 p++; 101 p++;
(...skipping 23 matching lines...) Expand all
215 stream.Put(*p); 125 stream.Put(*p);
216 } 126 }
217 } 127 }
218 SmartPointer<const char> expanded = stream.ToCString(); 128 SmartPointer<const char> expanded = stream.ToCString();
219 OpenFile(*expanded); 129 OpenFile(*expanded);
220 } else { 130 } else {
221 OpenFile(FLAG_logfile); 131 OpenFile(FLAG_logfile);
222 } 132 }
223 } 133 }
224 } 134 }
225 #endif
226 } 135 }
227 136
228 137
229 void Log::OpenStdout() { 138 void Log::OpenStdout() {
230 ASSERT(!IsEnabled()); 139 ASSERT(!IsEnabled());
231 output_handle_ = stdout; 140 output_handle_ = stdout;
232 write_to_file_ = true; 141 }
142
143
144 void Log::OpenTemporaryFile() {
145 ASSERT(!IsEnabled());
146 output_handle_ = i::OS::OpenTemporaryFile();
233 } 147 }
234 148
235 149
236 // Extension added to V8 log file name to get the low-level log name. 150 // Extension added to V8 log file name to get the low-level log name.
237 static const char kLowLevelLogExt[] = ".ll"; 151 static const char kLowLevelLogExt[] = ".ll";
238 152
239 // File buffer size of the low-level log. We don't use the default to 153 // File buffer size of the low-level log. We don't use the default to
240 // minimize the associated overhead. 154 // minimize the associated overhead.
241 static const int kLowLevelLogBufferSize = 2 * MB; 155 static const int kLowLevelLogBufferSize = 2 * MB;
242 156
243 157
244 void Log::OpenFile(const char* name) { 158 void Log::OpenFile(const char* name) {
245 ASSERT(!IsEnabled()); 159 ASSERT(!IsEnabled());
246 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); 160 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
247 write_to_file_ = true;
248 if (FLAG_ll_prof) { 161 if (FLAG_ll_prof) {
249 // Open the low-level log file. 162 // Open the low-level log file.
250 size_t len = strlen(name); 163 size_t len = strlen(name);
251 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt))); 164 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt)));
252 memcpy(ll_name.start(), name, len); 165 memcpy(ll_name.start(), name, len);
253 memcpy(ll_name.start() + len, kLowLevelLogExt, sizeof(kLowLevelLogExt)); 166 memcpy(ll_name.start() + len, kLowLevelLogExt, sizeof(kLowLevelLogExt));
254 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); 167 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
255 setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize); 168 setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize);
256 } 169 }
257 } 170 }
258 171
259 172
260 void Log::OpenMemoryBuffer() { 173 FILE* Log::Close() {
261 ASSERT(!IsEnabled()); 174 FILE* result = NULL;
262 output_buffer_ = new LogDynamicBuffer( 175 if (output_handle_ != NULL) {
263 kDynamicBufferBlockSize, kMaxDynamicBufferSize, 176 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
264 kDynamicBufferSeal, StrLength(kDynamicBufferSeal)); 177 fclose(output_handle_);
265 write_to_file_ = false; 178 } else {
266 } 179 result = output_handle_;
267 180 }
268
269 void Log::Close() {
270 if (write_to_file_) {
271 if (output_handle_ != NULL) fclose(output_handle_);
272 output_handle_ = NULL;
273 if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
274 ll_output_handle_ = NULL;
275 } else {
276 delete output_buffer_;
277 output_buffer_ = NULL;
278 } 181 }
182 output_handle_ = NULL;
183 if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
184 ll_output_handle_ = NULL;
279 185
280 DeleteArray(message_buffer_); 186 DeleteArray(message_buffer_);
281 message_buffer_ = NULL; 187 message_buffer_ = NULL;
282 188
283 delete mutex_; 189 delete mutex_;
284 mutex_ = NULL; 190 mutex_ = NULL;
285 191
286 is_stopped_ = false; 192 is_stopped_ = false;
287 } 193 return result;
288
289
290 int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
291 if (write_to_file_) return 0;
292 ASSERT(output_buffer_ != NULL);
293 ASSERT(from_pos >= 0);
294 ASSERT(max_size >= 0);
295 int actual_size = output_buffer_->Read(from_pos, dest_buf, max_size);
296 ASSERT(actual_size <= max_size);
297 if (actual_size == 0) return 0;
298
299 // Find previous log line boundary.
300 char* end_pos = dest_buf + actual_size - 1;
301 while (end_pos >= dest_buf && *end_pos != '\n') --end_pos;
302 actual_size = static_cast<int>(end_pos - dest_buf + 1);
303 // If the assertion below is hit, it means that there was no line end
304 // found --- something wrong has happened.
305 ASSERT(actual_size > 0);
306 ASSERT(actual_size <= max_size);
307 return actual_size;
308 } 194 }
309 195
310 196
311 LogMessageBuilder::LogMessageBuilder(Logger* logger) 197 LogMessageBuilder::LogMessageBuilder(Logger* logger)
312 : log_(logger->log_), 198 : log_(logger->log_),
313 sl(log_->mutex_), 199 sl(log_->mutex_),
314 pos_(0) { 200 pos_(0) {
315 ASSERT(log_->message_buffer_ != NULL); 201 ASSERT(log_->message_buffer_ != NULL);
316 } 202 }
317 203
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 Vector<char> buf(log_->message_buffer_ + pos_, 292 Vector<char> buf(log_->message_buffer_ + pos_,
407 Log::kMessageBufferSize - pos_); 293 Log::kMessageBufferSize - pos_);
408 OS::StrNCpy(buf, str, len); 294 OS::StrNCpy(buf, str, len);
409 pos_ += len; 295 pos_ += len;
410 ASSERT(pos_ <= Log::kMessageBufferSize); 296 ASSERT(pos_ <= Log::kMessageBufferSize);
411 } 297 }
412 298
413 299
414 void LogMessageBuilder::WriteToLogFile() { 300 void LogMessageBuilder::WriteToLogFile() {
415 ASSERT(pos_ <= Log::kMessageBufferSize); 301 ASSERT(pos_ <= Log::kMessageBufferSize);
416 const int written = log_->write_to_file_ ? 302 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
417 log_->WriteToFile(log_->message_buffer_, pos_) :
418 log_->WriteToMemory(log_->message_buffer_, pos_);
419 if (written != pos_) { 303 if (written != pos_) {
420 log_->stop(); 304 log_->stop();
421 log_->logger_->LogFailure(); 305 log_->logger_->LogFailure();
422 } 306 }
423 } 307 }
424 308
425 309
426 #endif // ENABLE_LOGGING_AND_PROFILING
427
428 } } // namespace v8::internal 310 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/log-utils.h ('k') | src/macros.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698