OLD | NEW |
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 17 matching lines...) Expand all Loading... |
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 | 36 |
37 const char* const Log::kLogToTemporaryFile = "&"; | 37 const char* const Log::kLogToTemporaryFile = "&"; |
| 38 const char* const Log::kLogToConsole = "-"; |
38 | 39 |
39 | 40 |
40 Log::Log(Logger* logger) | 41 Log::Log(Logger* logger) |
41 : is_stopped_(false), | 42 : is_stopped_(false), |
42 output_handle_(NULL), | 43 output_handle_(NULL), |
43 ll_output_handle_(NULL), | |
44 mutex_(NULL), | 44 mutex_(NULL), |
45 message_buffer_(NULL), | 45 message_buffer_(NULL), |
46 logger_(logger) { | 46 logger_(logger) { |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 static void AddIsolateIdIfNeeded(StringStream* stream) { | 50 void Log::Initialize(const char* log_file_name) { |
51 Isolate* isolate = Isolate::Current(); | |
52 if (isolate->IsDefaultIsolate()) return; | |
53 stream->Add("isolate-%p-", isolate); | |
54 } | |
55 | |
56 | |
57 void Log::Initialize() { | |
58 mutex_ = OS::CreateMutex(); | 51 mutex_ = OS::CreateMutex(); |
59 message_buffer_ = NewArray<char>(kMessageBufferSize); | 52 message_buffer_ = NewArray<char>(kMessageBufferSize); |
60 | 53 |
61 // --log-all enables all the log flags. | 54 // --log-all enables all the log flags. |
62 if (FLAG_log_all) { | 55 if (FLAG_log_all) { |
63 FLAG_log_runtime = true; | 56 FLAG_log_runtime = true; |
64 FLAG_log_api = true; | 57 FLAG_log_api = true; |
65 FLAG_log_code = true; | 58 FLAG_log_code = true; |
66 FLAG_log_gc = true; | 59 FLAG_log_gc = true; |
67 FLAG_log_suspect = true; | 60 FLAG_log_suspect = true; |
68 FLAG_log_handles = true; | 61 FLAG_log_handles = true; |
69 FLAG_log_regexp = true; | 62 FLAG_log_regexp = true; |
70 FLAG_log_internal_timer_events = true; | 63 FLAG_log_internal_timer_events = true; |
71 } | 64 } |
72 | 65 |
73 // --prof implies --log-code. | 66 // --prof implies --log-code. |
74 if (FLAG_prof) FLAG_log_code = true; | 67 if (FLAG_prof) FLAG_log_code = true; |
75 | 68 |
76 // --prof_lazy controls --log-code, implies --noprof_auto. | 69 // --prof_lazy controls --log-code, implies --noprof_auto. |
77 if (FLAG_prof_lazy) { | 70 if (FLAG_prof_lazy) { |
78 FLAG_log_code = false; | 71 FLAG_log_code = false; |
79 FLAG_prof_auto = false; | 72 FLAG_prof_auto = false; |
80 } | 73 } |
81 | 74 |
82 // If we're logging anything, we need to open the log file. | 75 // If we're logging anything, we need to open the log file. |
83 if (Log::InitLogAtStart()) { | 76 if (Log::InitLogAtStart()) { |
84 if (strcmp(FLAG_logfile, "-") == 0) { | 77 if (strcmp(log_file_name, kLogToConsole) == 0) { |
85 OpenStdout(); | 78 OpenStdout(); |
86 } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) { | 79 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) { |
87 OpenTemporaryFile(); | 80 OpenTemporaryFile(); |
88 } else { | 81 } else { |
89 if (strchr(FLAG_logfile, '%') != NULL || | 82 OpenFile(log_file_name); |
90 !Isolate::Current()->IsDefaultIsolate()) { | |
91 // If there's a '%' in the log file name we have to expand | |
92 // placeholders. | |
93 HeapStringAllocator allocator; | |
94 StringStream stream(&allocator); | |
95 AddIsolateIdIfNeeded(&stream); | |
96 for (const char* p = FLAG_logfile; *p; p++) { | |
97 if (*p == '%') { | |
98 p++; | |
99 switch (*p) { | |
100 case '\0': | |
101 // If there's a % at the end of the string we back up | |
102 // one character so we can escape the loop properly. | |
103 p--; | |
104 break; | |
105 case 'p': | |
106 stream.Add("%d", OS::GetCurrentProcessId()); | |
107 break; | |
108 case 't': { | |
109 // %t expands to the current time in milliseconds. | |
110 double time = OS::TimeCurrentMillis(); | |
111 stream.Add("%.0f", FmtElm(time)); | |
112 break; | |
113 } | |
114 case '%': | |
115 // %% expands (contracts really) to %. | |
116 stream.Put('%'); | |
117 break; | |
118 default: | |
119 // All other %'s expand to themselves. | |
120 stream.Put('%'); | |
121 stream.Put(*p); | |
122 break; | |
123 } | |
124 } else { | |
125 stream.Put(*p); | |
126 } | |
127 } | |
128 SmartArrayPointer<const char> expanded = stream.ToCString(); | |
129 OpenFile(*expanded); | |
130 } else { | |
131 OpenFile(FLAG_logfile); | |
132 } | |
133 } | 83 } |
134 } | 84 } |
135 } | 85 } |
136 | 86 |
137 | 87 |
138 void Log::OpenStdout() { | 88 void Log::OpenStdout() { |
139 ASSERT(!IsEnabled()); | 89 ASSERT(!IsEnabled()); |
140 output_handle_ = stdout; | 90 output_handle_ = stdout; |
141 } | 91 } |
142 | 92 |
143 | 93 |
144 void Log::OpenTemporaryFile() { | 94 void Log::OpenTemporaryFile() { |
145 ASSERT(!IsEnabled()); | 95 ASSERT(!IsEnabled()); |
146 output_handle_ = i::OS::OpenTemporaryFile(); | 96 output_handle_ = i::OS::OpenTemporaryFile(); |
147 } | 97 } |
148 | 98 |
149 | 99 |
150 // Extension added to V8 log file name to get the low-level log name. | |
151 static const char kLowLevelLogExt[] = ".ll"; | |
152 | |
153 // File buffer size of the low-level log. We don't use the default to | |
154 // minimize the associated overhead. | |
155 static const int kLowLevelLogBufferSize = 2 * MB; | |
156 | |
157 | |
158 void Log::OpenFile(const char* name) { | 100 void Log::OpenFile(const char* name) { |
159 ASSERT(!IsEnabled()); | 101 ASSERT(!IsEnabled()); |
160 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); | 102 output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); |
161 if (FLAG_ll_prof) { | |
162 // Open the low-level log file. | |
163 size_t len = strlen(name); | |
164 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt))); | |
165 OS::MemCopy(ll_name.start(), name, len); | |
166 OS::MemCopy(ll_name.start() + len, | |
167 kLowLevelLogExt, sizeof(kLowLevelLogExt)); | |
168 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); | |
169 setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize); | |
170 } | |
171 } | 103 } |
172 | 104 |
173 | 105 |
174 FILE* Log::Close() { | 106 FILE* Log::Close() { |
175 FILE* result = NULL; | 107 FILE* result = NULL; |
176 if (output_handle_ != NULL) { | 108 if (output_handle_ != NULL) { |
177 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) { | 109 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) { |
178 fclose(output_handle_); | 110 fclose(output_handle_); |
179 } else { | 111 } else { |
180 result = output_handle_; | 112 result = output_handle_; |
181 } | 113 } |
182 } | 114 } |
183 output_handle_ = NULL; | 115 output_handle_ = NULL; |
184 if (ll_output_handle_ != NULL) fclose(ll_output_handle_); | |
185 ll_output_handle_ = NULL; | |
186 | 116 |
187 DeleteArray(message_buffer_); | 117 DeleteArray(message_buffer_); |
188 message_buffer_ = NULL; | 118 message_buffer_ = NULL; |
189 | 119 |
190 delete mutex_; | 120 delete mutex_; |
191 mutex_ = NULL; | 121 mutex_ = NULL; |
192 | 122 |
193 is_stopped_ = false; | 123 is_stopped_ = false; |
194 return result; | 124 return result; |
195 } | 125 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 ASSERT(pos_ <= Log::kMessageBufferSize); | 244 ASSERT(pos_ <= Log::kMessageBufferSize); |
315 const int written = log_->WriteToFile(log_->message_buffer_, pos_); | 245 const int written = log_->WriteToFile(log_->message_buffer_, pos_); |
316 if (written != pos_) { | 246 if (written != pos_) { |
317 log_->stop(); | 247 log_->stop(); |
318 log_->logger_->LogFailure(); | 248 log_->logger_->LogFailure(); |
319 } | 249 } |
320 } | 250 } |
321 | 251 |
322 | 252 |
323 } } // namespace v8::internal | 253 } } // namespace v8::internal |
OLD | NEW |