OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 namespace internal { | 47 namespace internal { |
48 | 48 |
49 | 49 |
50 #define DECLARE_EVENT(ignore1, name) name, | 50 #define DECLARE_EVENT(ignore1, name) name, |
51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | 52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) |
53 }; | 53 }; |
54 #undef DECLARE_EVENT | 54 #undef DECLARE_EVENT |
55 | 55 |
56 | 56 |
| 57 #define CALL_LISTENERS(Call) \ |
| 58 for (int i = 0; i < listeners_.length(); ++i) { \ |
| 59 listeners_[i]->Call; \ |
| 60 } |
| 61 |
| 62 #define PROFILER_LOG(Call) \ |
| 63 do { \ |
| 64 CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \ |
| 65 if (cpu_profiler->is_profiling()) { \ |
| 66 cpu_profiler->Call; \ |
| 67 } \ |
| 68 } while (false); |
| 69 |
57 // ComputeMarker must only be used when SharedFunctionInfo is known. | 70 // ComputeMarker must only be used when SharedFunctionInfo is known. |
58 static const char* ComputeMarker(Code* code) { | 71 static const char* ComputeMarker(Code* code) { |
59 switch (code->kind()) { | 72 switch (code->kind()) { |
60 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | 73 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
61 case Code::OPTIMIZED_FUNCTION: return "*"; | 74 case Code::OPTIMIZED_FUNCTION: return "*"; |
62 default: return ""; | 75 default: return ""; |
63 } | 76 } |
64 } | 77 } |
65 | 78 |
66 | 79 |
67 class CodeEventLogger { | 80 class CodeEventLogger::NameBuffer { |
68 public: | 81 public: |
69 virtual ~CodeEventLogger() { } | 82 NameBuffer() { Reset(); } |
70 | 83 |
71 void CodeCreateEvent(Logger::LogEventsAndTags tag, | 84 void Reset() { |
72 Code* code, | 85 utf8_pos_ = 0; |
73 const char* comment); | 86 } |
74 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
75 Code* code, | |
76 Name* name); | |
77 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
78 Code* code, | |
79 int args_count); | |
80 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
81 Code* code, | |
82 SharedFunctionInfo* shared, | |
83 CompilationInfo* info, | |
84 Name* name); | |
85 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
86 Code* code, | |
87 SharedFunctionInfo* shared, | |
88 CompilationInfo* info, | |
89 Name* source, | |
90 int line); | |
91 void RegExpCodeCreateEvent(Code* code, String* source); | |
92 | 87 |
93 protected: | 88 void Init(Logger::LogEventsAndTags tag) { |
94 class NameBuffer { | 89 Reset(); |
95 public: | 90 AppendBytes(kLogEventsNames[tag]); |
96 NameBuffer() { Reset(); } | 91 AppendByte(':'); |
| 92 } |
97 | 93 |
98 void Reset() { | 94 void AppendName(Name* name) { |
99 utf8_pos_ = 0; | 95 if (name->IsString()) { |
| 96 AppendString(String::cast(name)); |
| 97 } else { |
| 98 Symbol* symbol = Symbol::cast(name); |
| 99 AppendBytes("symbol("); |
| 100 if (!symbol->name()->IsUndefined()) { |
| 101 AppendBytes("\""); |
| 102 AppendString(String::cast(symbol->name())); |
| 103 AppendBytes("\" "); |
| 104 } |
| 105 AppendBytes("hash "); |
| 106 AppendHex(symbol->Hash()); |
| 107 AppendByte(')'); |
100 } | 108 } |
| 109 } |
101 | 110 |
102 void Init(Logger::LogEventsAndTags tag) { | 111 void AppendString(String* str) { |
103 Reset(); | 112 if (str == NULL) return; |
104 AppendBytes(kLogEventsNames[tag]); | 113 int uc16_length = Min(str->length(), kUtf16BufferSize); |
105 AppendByte(':'); | 114 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); |
| 115 int previous = unibrow::Utf16::kNoPreviousCharacter; |
| 116 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { |
| 117 uc16 c = utf16_buffer[i]; |
| 118 if (c <= unibrow::Utf8::kMaxOneByteChar) { |
| 119 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); |
| 120 } else { |
| 121 int char_length = unibrow::Utf8::Length(c, previous); |
| 122 if (utf8_pos_ + char_length > kUtf8BufferSize) break; |
| 123 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); |
| 124 utf8_pos_ += char_length; |
| 125 } |
| 126 previous = c; |
106 } | 127 } |
| 128 } |
107 | 129 |
108 void AppendName(Name* name) { | 130 void AppendBytes(const char* bytes, int size) { |
109 if (name->IsString()) { | 131 size = Min(size, kUtf8BufferSize - utf8_pos_); |
110 AppendString(String::cast(name)); | 132 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); |
111 } else { | 133 utf8_pos_ += size; |
112 Symbol* symbol = Symbol::cast(name); | 134 } |
113 AppendBytes("symbol("); | |
114 if (!symbol->name()->IsUndefined()) { | |
115 AppendBytes("\""); | |
116 AppendString(String::cast(symbol->name())); | |
117 AppendBytes("\" "); | |
118 } | |
119 AppendBytes("hash "); | |
120 AppendHex(symbol->Hash()); | |
121 AppendByte(')'); | |
122 } | |
123 } | |
124 | 135 |
125 void AppendString(String* str) { | 136 void AppendBytes(const char* bytes) { |
126 if (str == NULL) return; | 137 AppendBytes(bytes, StrLength(bytes)); |
127 int uc16_length = Min(str->length(), kUtf16BufferSize); | 138 } |
128 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); | |
129 int previous = unibrow::Utf16::kNoPreviousCharacter; | |
130 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
131 uc16 c = utf16_buffer[i]; | |
132 if (c <= unibrow::Utf8::kMaxOneByteChar) { | |
133 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); | |
134 } else { | |
135 int char_length = unibrow::Utf8::Length(c, previous); | |
136 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
137 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); | |
138 utf8_pos_ += char_length; | |
139 } | |
140 previous = c; | |
141 } | |
142 } | |
143 | 139 |
144 void AppendBytes(const char* bytes, int size) { | 140 void AppendByte(char c) { |
145 size = Min(size, kUtf8BufferSize - utf8_pos_); | 141 if (utf8_pos_ >= kUtf8BufferSize) return; |
146 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); | 142 utf8_buffer_[utf8_pos_++] = c; |
| 143 } |
| 144 |
| 145 void AppendInt(int n) { |
| 146 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 147 kUtf8BufferSize - utf8_pos_); |
| 148 int size = OS::SNPrintF(buffer, "%d", n); |
| 149 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
147 utf8_pos_ += size; | 150 utf8_pos_ += size; |
148 } | 151 } |
| 152 } |
149 | 153 |
150 void AppendBytes(const char* bytes) { | 154 void AppendHex(uint32_t n) { |
151 AppendBytes(bytes, StrLength(bytes)); | 155 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 156 kUtf8BufferSize - utf8_pos_); |
| 157 int size = OS::SNPrintF(buffer, "%x", n); |
| 158 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| 159 utf8_pos_ += size; |
152 } | 160 } |
| 161 } |
153 | 162 |
154 void AppendByte(char c) { | 163 const char* get() { return utf8_buffer_; } |
155 if (utf8_pos_ >= kUtf8BufferSize) return; | 164 int size() const { return utf8_pos_; } |
156 utf8_buffer_[utf8_pos_++] = c; | |
157 } | |
158 | |
159 void AppendInt(int n) { | |
160 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
161 kUtf8BufferSize - utf8_pos_); | |
162 int size = OS::SNPrintF(buffer, "%d", n); | |
163 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
164 utf8_pos_ += size; | |
165 } | |
166 } | |
167 | |
168 void AppendHex(uint32_t n) { | |
169 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
170 kUtf8BufferSize - utf8_pos_); | |
171 int size = OS::SNPrintF(buffer, "%x", n); | |
172 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
173 utf8_pos_ += size; | |
174 } | |
175 } | |
176 | |
177 const char* get() { return utf8_buffer_; } | |
178 int size() const { return utf8_pos_; } | |
179 | |
180 private: | |
181 static const int kUtf8BufferSize = 512; | |
182 static const int kUtf16BufferSize = 128; | |
183 | |
184 int utf8_pos_; | |
185 char utf8_buffer_[kUtf8BufferSize]; | |
186 uc16 utf16_buffer[kUtf16BufferSize]; | |
187 }; | |
188 | 165 |
189 private: | 166 private: |
190 virtual void LogRecordedBuffer(Code* code, | 167 static const int kUtf8BufferSize = 512; |
191 SharedFunctionInfo* shared, | 168 static const int kUtf16BufferSize = 128; |
192 NameBuffer* name_buffer) = 0; | |
193 | 169 |
194 NameBuffer name_buffer_; | 170 int utf8_pos_; |
| 171 char utf8_buffer_[kUtf8BufferSize]; |
| 172 uc16 utf16_buffer[kUtf16BufferSize]; |
195 }; | 173 }; |
196 | 174 |
197 | 175 |
| 176 CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { } |
| 177 |
| 178 CodeEventLogger::~CodeEventLogger() { delete name_buffer_; } |
| 179 |
| 180 |
198 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 181 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
199 Code* code, | 182 Code* code, |
200 const char* comment) { | 183 const char* comment) { |
201 name_buffer_.Init(tag); | 184 name_buffer_->Init(tag); |
202 name_buffer_.AppendBytes(comment); | 185 name_buffer_->AppendBytes(comment); |
203 LogRecordedBuffer(code, NULL, &name_buffer_); | 186 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
204 } | 187 } |
205 | 188 |
206 | 189 |
207 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 190 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
208 Code* code, | 191 Code* code, |
209 Name* name) { | 192 Name* name) { |
210 name_buffer_.Init(tag); | 193 name_buffer_->Init(tag); |
211 name_buffer_.AppendName(name); | 194 name_buffer_->AppendName(name); |
212 LogRecordedBuffer(code, NULL, &name_buffer_); | 195 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
213 } | 196 } |
214 | 197 |
215 | 198 |
216 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 199 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
217 Code* code, | 200 Code* code, |
218 SharedFunctionInfo* shared, | 201 SharedFunctionInfo* shared, |
219 CompilationInfo* info, | 202 CompilationInfo* info, |
220 Name* name) { | 203 Name* name) { |
221 name_buffer_.Init(tag); | 204 name_buffer_->Init(tag); |
222 name_buffer_.AppendBytes(ComputeMarker(code)); | 205 name_buffer_->AppendBytes(ComputeMarker(code)); |
223 name_buffer_.AppendName(name); | 206 name_buffer_->AppendName(name); |
224 LogRecordedBuffer(code, shared, &name_buffer_); | 207 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
225 } | 208 } |
226 | 209 |
227 | 210 |
228 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 211 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
229 Code* code, | 212 Code* code, |
230 SharedFunctionInfo* shared, | 213 SharedFunctionInfo* shared, |
231 CompilationInfo* info, | 214 CompilationInfo* info, |
232 Name* source, int line) { | 215 Name* source, int line) { |
233 name_buffer_.Init(tag); | 216 name_buffer_->Init(tag); |
234 name_buffer_.AppendBytes(ComputeMarker(code)); | 217 name_buffer_->AppendBytes(ComputeMarker(code)); |
235 name_buffer_.AppendString(shared->DebugName()); | 218 name_buffer_->AppendString(shared->DebugName()); |
236 name_buffer_.AppendByte(' '); | 219 name_buffer_->AppendByte(' '); |
237 if (source->IsString()) { | 220 if (source->IsString()) { |
238 name_buffer_.AppendString(String::cast(source)); | 221 name_buffer_->AppendString(String::cast(source)); |
239 } else { | 222 } else { |
240 name_buffer_.AppendBytes("symbol(hash "); | 223 name_buffer_->AppendBytes("symbol(hash "); |
241 name_buffer_.AppendHex(Name::cast(source)->Hash()); | 224 name_buffer_->AppendHex(Name::cast(source)->Hash()); |
242 name_buffer_.AppendByte(')'); | 225 name_buffer_->AppendByte(')'); |
243 } | 226 } |
244 name_buffer_.AppendByte(':'); | 227 name_buffer_->AppendByte(':'); |
245 name_buffer_.AppendInt(line); | 228 name_buffer_->AppendInt(line); |
246 LogRecordedBuffer(code, shared, &name_buffer_); | 229 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
247 } | 230 } |
248 | 231 |
249 | 232 |
250 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 233 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
251 Code* code, | 234 Code* code, |
252 int args_count) { | 235 int args_count) { |
253 name_buffer_.Init(tag); | 236 name_buffer_->Init(tag); |
254 name_buffer_.AppendInt(args_count); | 237 name_buffer_->AppendInt(args_count); |
255 LogRecordedBuffer(code, NULL, &name_buffer_); | 238 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
256 } | 239 } |
257 | 240 |
258 | 241 |
259 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { | 242 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { |
260 name_buffer_.Init(Logger::REG_EXP_TAG); | 243 name_buffer_->Init(Logger::REG_EXP_TAG); |
261 name_buffer_.AppendString(source); | 244 name_buffer_->AppendString(source); |
262 LogRecordedBuffer(code, NULL, &name_buffer_); | 245 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
263 } | 246 } |
264 | 247 |
265 | 248 |
266 // Low-level logging support. | 249 // Low-level logging support. |
| 250 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 251 |
267 class LowLevelLogger : public CodeEventLogger { | 252 class LowLevelLogger : public CodeEventLogger { |
268 public: | 253 public: |
269 explicit LowLevelLogger(const char* file_name); | 254 explicit LowLevelLogger(const char* file_name); |
270 virtual ~LowLevelLogger(); | 255 virtual ~LowLevelLogger(); |
271 | 256 |
272 void CodeMoveEvent(Address from, Address to); | 257 virtual void CodeMoveEvent(Address from, Address to); |
273 void CodeDeleteEvent(Address from); | 258 virtual void CodeDeleteEvent(Address from); |
274 void SnapshotPositionEvent(Address addr, int pos); | 259 virtual void SnapshotPositionEvent(Address addr, int pos); |
275 void CodeMovingGCEvent(); | 260 virtual void CodeMovingGCEvent(); |
276 | 261 |
277 private: | 262 private: |
278 virtual void LogRecordedBuffer(Code* code, | 263 virtual void LogRecordedBuffer(Code* code, |
279 SharedFunctionInfo* shared, | 264 SharedFunctionInfo* shared, |
280 NameBuffer* name_buffer); | 265 const char* name, |
| 266 int length); |
281 | 267 |
282 // Low-level profiling event structures. | 268 // Low-level profiling event structures. |
283 struct CodeCreateStruct { | 269 struct CodeCreateStruct { |
284 static const char kTag = 'C'; | 270 static const char kTag = 'C'; |
285 | 271 |
286 int32_t name_size; | 272 int32_t name_size; |
287 Address code_address; | 273 Address code_address; |
288 int32_t code_size; | 274 int32_t code_size; |
289 }; | 275 }; |
290 | 276 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 const char arch[] = "mips"; | 354 const char arch[] = "mips"; |
369 #else | 355 #else |
370 const char arch[] = "unknown"; | 356 const char arch[] = "unknown"; |
371 #endif | 357 #endif |
372 LogWriteBytes(arch, sizeof(arch)); | 358 LogWriteBytes(arch, sizeof(arch)); |
373 } | 359 } |
374 | 360 |
375 | 361 |
376 void LowLevelLogger::LogRecordedBuffer(Code* code, | 362 void LowLevelLogger::LogRecordedBuffer(Code* code, |
377 SharedFunctionInfo*, | 363 SharedFunctionInfo*, |
378 NameBuffer* name_buffer) { | 364 const char* name, |
| 365 int length) { |
379 CodeCreateStruct event; | 366 CodeCreateStruct event; |
380 event.name_size = name_buffer->size(); | 367 event.name_size = length; |
381 event.code_address = code->instruction_start(); | 368 event.code_address = code->instruction_start(); |
382 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | 369 ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
383 event.code_size = code->instruction_size(); | 370 event.code_size = code->instruction_size(); |
384 LogWriteStruct(event); | 371 LogWriteStruct(event); |
385 LogWriteBytes(name_buffer->get(), name_buffer->size()); | 372 LogWriteBytes(name, length); |
386 LogWriteBytes( | 373 LogWriteBytes( |
387 reinterpret_cast<const char*>(code->instruction_start()), | 374 reinterpret_cast<const char*>(code->instruction_start()), |
388 code->instruction_size()); | 375 code->instruction_size()); |
389 } | 376 } |
390 | 377 |
391 | 378 |
392 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | 379 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { |
393 CodeMoveStruct event; | 380 CodeMoveStruct event; |
394 event.from_address = from + Code::kHeaderSize; | 381 event.from_address = from + Code::kHeaderSize; |
395 event.to_address = to + Code::kHeaderSize; | 382 event.to_address = to + Code::kHeaderSize; |
(...skipping 23 matching lines...) Expand all Loading... |
419 } | 406 } |
420 | 407 |
421 | 408 |
422 void LowLevelLogger::CodeMovingGCEvent() { | 409 void LowLevelLogger::CodeMovingGCEvent() { |
423 const char tag = kCodeMovingGCTag; | 410 const char tag = kCodeMovingGCTag; |
424 | 411 |
425 LogWriteBytes(&tag, sizeof(tag)); | 412 LogWriteBytes(&tag, sizeof(tag)); |
426 } | 413 } |
427 | 414 |
428 | 415 |
429 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 416 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
430 | |
431 | |
432 class CodeAddressMap: public CodeEventLogger { | |
433 public: | |
434 CodeAddressMap() { } | |
435 virtual ~CodeAddressMap() { } | |
436 | |
437 void CodeMoveEvent(Address from, Address to) { | |
438 address_to_name_map_.Move(from, to); | |
439 } | |
440 | |
441 void CodeDeleteEvent(Address from) { | |
442 address_to_name_map_.Remove(from); | |
443 } | |
444 | |
445 const char* Lookup(Address address) { | |
446 return address_to_name_map_.Lookup(address); | |
447 } | |
448 | |
449 private: | |
450 class NameMap { | |
451 public: | |
452 NameMap() : impl_(&PointerEquals) {} | |
453 | |
454 ~NameMap() { | |
455 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | |
456 DeleteArray(static_cast<const char*>(p->value)); | |
457 } | |
458 } | |
459 | |
460 void Insert(Address code_address, const char* name, int name_size) { | |
461 HashMap::Entry* entry = FindOrCreateEntry(code_address); | |
462 if (entry->value == NULL) { | |
463 entry->value = CopyName(name, name_size); | |
464 } | |
465 } | |
466 | |
467 const char* Lookup(Address code_address) { | |
468 HashMap::Entry* entry = FindEntry(code_address); | |
469 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; | |
470 } | |
471 | |
472 void Remove(Address code_address) { | |
473 HashMap::Entry* entry = FindEntry(code_address); | |
474 if (entry != NULL) { | |
475 DeleteArray(static_cast<char*>(entry->value)); | |
476 RemoveEntry(entry); | |
477 } | |
478 } | |
479 | |
480 void Move(Address from, Address to) { | |
481 if (from == to) return; | |
482 HashMap::Entry* from_entry = FindEntry(from); | |
483 ASSERT(from_entry != NULL); | |
484 void* value = from_entry->value; | |
485 RemoveEntry(from_entry); | |
486 HashMap::Entry* to_entry = FindOrCreateEntry(to); | |
487 ASSERT(to_entry->value == NULL); | |
488 to_entry->value = value; | |
489 } | |
490 | |
491 private: | |
492 static bool PointerEquals(void* lhs, void* rhs) { | |
493 return lhs == rhs; | |
494 } | |
495 | |
496 static char* CopyName(const char* name, int name_size) { | |
497 char* result = NewArray<char>(name_size + 1); | |
498 for (int i = 0; i < name_size; ++i) { | |
499 char c = name[i]; | |
500 if (c == '\0') c = ' '; | |
501 result[i] = c; | |
502 } | |
503 result[name_size] = '\0'; | |
504 return result; | |
505 } | |
506 | |
507 HashMap::Entry* FindOrCreateEntry(Address code_address) { | |
508 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); | |
509 } | |
510 | |
511 HashMap::Entry* FindEntry(Address code_address) { | |
512 return impl_.Lookup(code_address, | |
513 ComputePointerHash(code_address), | |
514 false); | |
515 } | |
516 | |
517 void RemoveEntry(HashMap::Entry* entry) { | |
518 impl_.Remove(entry->key, entry->hash); | |
519 } | |
520 | |
521 HashMap impl_; | |
522 | |
523 DISALLOW_COPY_AND_ASSIGN(NameMap); | |
524 }; | |
525 | |
526 virtual void LogRecordedBuffer(Code* code, | |
527 SharedFunctionInfo*, | |
528 NameBuffer* name_buffer) { | |
529 address_to_name_map_.Insert(code->address(), | |
530 name_buffer->get(), | |
531 name_buffer->size()); | |
532 } | |
533 | |
534 NameMap address_to_name_map_; | |
535 }; | |
536 | |
537 | |
538 #define CODE_ADDRESS_MAP_LOG(Call)\ | |
539 if (Serializer::enabled()) code_address_map_->Call; | |
540 | 417 |
541 | 418 |
542 class JitLogger : public CodeEventLogger { | 419 class JitLogger : public CodeEventLogger { |
543 public: | 420 public: |
544 explicit JitLogger(JitCodeEventHandler code_event_handler); | 421 explicit JitLogger(JitCodeEventHandler code_event_handler); |
545 | 422 |
546 void CodeMovedEvent(Address from, Address to); | 423 virtual void CodeMoveEvent(Address from, Address to); |
547 void CodeDeleteEvent(Address from); | 424 virtual void CodeDeleteEvent(Address from); |
548 void AddCodeLinePosInfoEvent( | 425 virtual void AddCodeLinePosInfoEvent( |
549 void* jit_handler_data, | 426 void* jit_handler_data, |
550 int pc_offset, | 427 int pc_offset, |
551 int position, | 428 int position, |
552 JitCodeEvent::PositionType position_type); | 429 JitCodeEvent::PositionType position_type); |
| 430 |
553 void* StartCodePosInfoEvent(); | 431 void* StartCodePosInfoEvent(); |
554 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); | 432 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); |
555 | 433 |
556 private: | 434 private: |
557 virtual void LogRecordedBuffer(Code* code, | 435 virtual void LogRecordedBuffer(Code* code, |
558 SharedFunctionInfo* shared, | 436 SharedFunctionInfo* shared, |
559 CodeEventLogger::NameBuffer* name_buffer); | 437 const char* name, |
| 438 int length); |
560 | 439 |
561 JitCodeEventHandler code_event_handler_; | 440 JitCodeEventHandler code_event_handler_; |
562 }; | 441 }; |
563 | 442 |
564 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; | |
565 | |
566 | 443 |
567 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) | 444 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
568 : code_event_handler_(code_event_handler) { | 445 : code_event_handler_(code_event_handler) { |
569 } | 446 } |
570 | 447 |
571 | 448 |
572 void JitLogger::LogRecordedBuffer(Code* code, | 449 void JitLogger::LogRecordedBuffer(Code* code, |
573 SharedFunctionInfo* shared, | 450 SharedFunctionInfo* shared, |
574 CodeEventLogger::NameBuffer* name_buffer) { | 451 const char* name, |
| 452 int length) { |
575 JitCodeEvent event; | 453 JitCodeEvent event; |
576 memset(&event, 0, sizeof(event)); | 454 memset(&event, 0, sizeof(event)); |
577 event.type = JitCodeEvent::CODE_ADDED; | 455 event.type = JitCodeEvent::CODE_ADDED; |
578 event.code_start = code->instruction_start(); | 456 event.code_start = code->instruction_start(); |
579 event.code_len = code->instruction_size(); | 457 event.code_len = code->instruction_size(); |
580 Handle<Script> script_handle; | 458 Handle<Script> script_handle; |
581 if (shared && shared->script()->IsScript()) { | 459 if (shared && shared->script()->IsScript()) { |
582 script_handle = Handle<Script>(Script::cast(shared->script())); | 460 script_handle = Handle<Script>(Script::cast(shared->script())); |
583 } | 461 } |
584 event.script = ToApiHandle<v8::Script>(script_handle); | 462 event.script = ToApiHandle<v8::Script>(script_handle); |
585 event.name.str = name_buffer->get(); | 463 event.name.str = name; |
586 event.name.len = name_buffer->size(); | 464 event.name.len = length; |
587 code_event_handler_(&event); | 465 code_event_handler_(&event); |
588 } | 466 } |
589 | 467 |
590 | 468 |
591 void JitLogger::CodeMovedEvent(Address from, Address to) { | 469 void JitLogger::CodeMoveEvent(Address from, Address to) { |
592 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | 470 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
593 | 471 |
594 JitCodeEvent event; | 472 JitCodeEvent event; |
595 event.type = JitCodeEvent::CODE_MOVED; | 473 event.type = JitCodeEvent::CODE_MOVED; |
596 event.code_start = from_code->instruction_start(); | 474 event.code_start = from_code->instruction_start(); |
597 event.code_len = from_code->instruction_size(); | 475 event.code_len = from_code->instruction_size(); |
598 | 476 |
599 // Calculate the header size. | 477 // Calculate the header size. |
600 const size_t header_size = | 478 const size_t header_size = |
601 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | 479 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 Logger::Logger(Isolate* isolate) | 707 Logger::Logger(Isolate* isolate) |
830 : isolate_(isolate), | 708 : isolate_(isolate), |
831 ticker_(NULL), | 709 ticker_(NULL), |
832 profiler_(NULL), | 710 profiler_(NULL), |
833 log_events_(NULL), | 711 log_events_(NULL), |
834 logging_nesting_(0), | 712 logging_nesting_(0), |
835 cpu_profiler_nesting_(0), | 713 cpu_profiler_nesting_(0), |
836 log_(new Log(this)), | 714 log_(new Log(this)), |
837 ll_logger_(NULL), | 715 ll_logger_(NULL), |
838 jit_logger_(NULL), | 716 jit_logger_(NULL), |
839 code_address_map_(new CodeAddressMap), | 717 listeners_(5), |
840 is_initialized_(false), | 718 is_initialized_(false), |
841 last_address_(NULL), | 719 last_address_(NULL), |
842 prev_sp_(NULL), | 720 prev_sp_(NULL), |
843 prev_function_(NULL), | 721 prev_function_(NULL), |
844 prev_to_(NULL), | 722 prev_to_(NULL), |
845 prev_code_(NULL), | 723 prev_code_(NULL), |
846 epoch_(0) { | 724 epoch_(0) { |
847 } | 725 } |
848 | 726 |
849 | 727 |
850 Logger::~Logger() { | 728 Logger::~Logger() { |
851 delete code_address_map_; | |
852 delete log_; | 729 delete log_; |
853 } | 730 } |
854 | 731 |
855 | 732 |
| 733 void Logger::addCodeEventListener(CodeEventListener* listener) { |
| 734 ASSERT(!hasCodeEventListener(listener)); |
| 735 listeners_.Add(listener); |
| 736 } |
| 737 |
| 738 |
| 739 void Logger::removeCodeEventListener(CodeEventListener* listener) { |
| 740 ASSERT(hasCodeEventListener(listener)); |
| 741 listeners_.RemoveElement(listener); |
| 742 } |
| 743 |
| 744 |
| 745 bool Logger::hasCodeEventListener(CodeEventListener* listener) { |
| 746 return listeners_.Contains(listener); |
| 747 } |
| 748 |
| 749 |
856 void Logger::ProfilerBeginEvent() { | 750 void Logger::ProfilerBeginEvent() { |
857 if (!log_->IsEnabled()) return; | 751 if (!log_->IsEnabled()) return; |
858 Log::MessageBuilder msg(log_); | 752 Log::MessageBuilder msg(log_); |
859 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); | 753 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); |
860 msg.WriteToLogFile(); | 754 msg.WriteToLogFile(); |
861 } | 755 } |
862 | 756 |
863 | 757 |
864 void Logger::StringEvent(const char* name, const char* value) { | 758 void Logger::StringEvent(const char* name, const char* value) { |
865 if (FLAG_log) UncheckedStringEvent(name, value); | 759 if (FLAG_log) UncheckedStringEvent(name, value); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 } | 1096 } |
1203 | 1097 |
1204 | 1098 |
1205 void Logger::DeleteEventStatic(const char* name, void* object) { | 1099 void Logger::DeleteEventStatic(const char* name, void* object) { |
1206 Isolate::Current()->logger()->DeleteEvent(name, object); | 1100 Isolate::Current()->logger()->DeleteEvent(name, object); |
1207 } | 1101 } |
1208 | 1102 |
1209 | 1103 |
1210 void Logger::CallbackEventInternal(const char* prefix, Name* name, | 1104 void Logger::CallbackEventInternal(const char* prefix, Name* name, |
1211 Address entry_point) { | 1105 Address entry_point) { |
1212 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1106 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1213 Log::MessageBuilder msg(log_); | 1107 Log::MessageBuilder msg(log_); |
1214 msg.Append("%s,%s,-2,", | 1108 msg.Append("%s,%s,-2,", |
1215 kLogEventsNames[CODE_CREATION_EVENT], | 1109 kLogEventsNames[CODE_CREATION_EVENT], |
1216 kLogEventsNames[CALLBACK_TAG]); | 1110 kLogEventsNames[CALLBACK_TAG]); |
1217 msg.AppendAddress(entry_point); | 1111 msg.AppendAddress(entry_point); |
1218 if (name->IsString()) { | 1112 if (name->IsString()) { |
1219 SmartArrayPointer<char> str = | 1113 SmartArrayPointer<char> str = |
1220 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1114 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
1221 msg.Append(",1,\"%s%s\"", prefix, *str); | 1115 msg.Append(",1,\"%s%s\"", prefix, *str); |
1222 } else { | 1116 } else { |
1223 Symbol* symbol = Symbol::cast(name); | 1117 Symbol* symbol = Symbol::cast(name); |
1224 if (symbol->name()->IsUndefined()) { | 1118 if (symbol->name()->IsUndefined()) { |
1225 msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash()); | 1119 msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash()); |
1226 } else { | 1120 } else { |
1227 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString( | 1121 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString( |
1228 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1122 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
1229 msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash()); | 1123 msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash()); |
1230 } | 1124 } |
1231 } | 1125 } |
1232 msg.Append('\n'); | 1126 msg.Append('\n'); |
1233 msg.WriteToLogFile(); | 1127 msg.WriteToLogFile(); |
1234 } | 1128 } |
1235 | 1129 |
1236 | 1130 |
1237 void Logger::CallbackEvent(Name* name, Address entry_point) { | 1131 void Logger::CallbackEvent(Name* name, Address entry_point) { |
1238 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1132 PROFILER_LOG(CallbackEvent(name, entry_point)); |
1239 CallbackEventInternal("", name, entry_point); | 1133 CallbackEventInternal("", name, entry_point); |
1240 } | 1134 } |
1241 | 1135 |
1242 | 1136 |
1243 void Logger::GetterCallbackEvent(Name* name, Address entry_point) { | 1137 void Logger::GetterCallbackEvent(Name* name, Address entry_point) { |
1244 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1138 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); |
1245 CallbackEventInternal("get ", name, entry_point); | 1139 CallbackEventInternal("get ", name, entry_point); |
1246 } | 1140 } |
1247 | 1141 |
1248 | 1142 |
1249 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1143 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
1250 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1144 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); |
1251 CallbackEventInternal("set ", name, entry_point); | 1145 CallbackEventInternal("set ", name, entry_point); |
1252 } | 1146 } |
1253 | 1147 |
1254 | 1148 |
1255 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, | 1149 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
1256 Logger::LogEventsAndTags tag, | 1150 Logger::LogEventsAndTags tag, |
1257 Code* code) { | 1151 Code* code) { |
1258 ASSERT(msg); | 1152 ASSERT(msg); |
1259 msg->Append("%s,%s,%d,", | 1153 msg->Append("%s,%s,%d,", |
1260 kLogEventsNames[Logger::CODE_CREATION_EVENT], | 1154 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
1261 kLogEventsNames[tag], | 1155 kLogEventsNames[tag], |
1262 code->kind()); | 1156 code->kind()); |
1263 msg->AppendAddress(code->address()); | 1157 msg->AppendAddress(code->address()); |
1264 msg->Append(",%d,", code->ExecutableSize()); | 1158 msg->Append(",%d,", code->ExecutableSize()); |
1265 } | 1159 } |
1266 | 1160 |
1267 | 1161 |
1268 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1162 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
1269 Code* code, | 1163 Code* code, |
1270 const char* comment) { | 1164 const char* comment) { |
| 1165 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); |
| 1166 |
1271 if (!is_logging_code_events()) return; | 1167 if (!is_logging_code_events()) return; |
1272 | 1168 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); |
1273 JIT_LOG(CodeCreateEvent(tag, code, comment)); | |
1274 LL_LOG(CodeCreateEvent(tag, code, comment)); | |
1275 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, comment)); | |
1276 | 1169 |
1277 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1170 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1278 Log::MessageBuilder msg(log_); | 1171 Log::MessageBuilder msg(log_); |
1279 AppendCodeCreateHeader(&msg, tag, code); | 1172 AppendCodeCreateHeader(&msg, tag, code); |
1280 msg.AppendDoubleQuotedString(comment); | 1173 msg.AppendDoubleQuotedString(comment); |
1281 msg.Append('\n'); | 1174 msg.Append('\n'); |
1282 msg.WriteToLogFile(); | 1175 msg.WriteToLogFile(); |
1283 } | 1176 } |
1284 | 1177 |
1285 | 1178 |
1286 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1179 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
1287 Code* code, | 1180 Code* code, |
1288 Name* name) { | 1181 Name* name) { |
| 1182 PROFILER_LOG(CodeCreateEvent(tag, code, name)); |
| 1183 |
1289 if (!is_logging_code_events()) return; | 1184 if (!is_logging_code_events()) return; |
1290 | 1185 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); |
1291 JIT_LOG(CodeCreateEvent(tag, code, name)); | |
1292 LL_LOG(CodeCreateEvent(tag, code, name)); | |
1293 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, name)); | |
1294 | 1186 |
1295 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1187 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1296 Log::MessageBuilder msg(log_); | 1188 Log::MessageBuilder msg(log_); |
1297 AppendCodeCreateHeader(&msg, tag, code); | 1189 AppendCodeCreateHeader(&msg, tag, code); |
1298 if (name->IsString()) { | 1190 if (name->IsString()) { |
1299 msg.Append('"'); | 1191 msg.Append('"'); |
1300 msg.AppendDetailed(String::cast(name), false); | 1192 msg.AppendDetailed(String::cast(name), false); |
1301 msg.Append('"'); | 1193 msg.Append('"'); |
1302 } else { | 1194 } else { |
1303 msg.AppendSymbolName(Symbol::cast(name)); | 1195 msg.AppendSymbolName(Symbol::cast(name)); |
1304 } | 1196 } |
1305 msg.Append('\n'); | 1197 msg.Append('\n'); |
1306 msg.WriteToLogFile(); | 1198 msg.WriteToLogFile(); |
1307 } | 1199 } |
1308 | 1200 |
1309 | 1201 |
1310 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1202 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
1311 Code* code, | 1203 Code* code, |
1312 SharedFunctionInfo* shared, | 1204 SharedFunctionInfo* shared, |
1313 CompilationInfo* info, | 1205 CompilationInfo* info, |
1314 Name* name) { | 1206 Name* name) { |
| 1207 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1208 |
1315 if (!is_logging_code_events()) return; | 1209 if (!is_logging_code_events()) return; |
1316 | 1210 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); |
1317 JIT_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
1318 LL_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
1319 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
1320 | 1211 |
1321 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1212 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1322 if (code == isolate_->builtins()->builtin( | 1213 if (code == isolate_->builtins()->builtin( |
1323 Builtins::kLazyCompile)) | 1214 Builtins::kLazyCompile)) |
1324 return; | 1215 return; |
1325 | 1216 |
1326 Log::MessageBuilder msg(log_); | 1217 Log::MessageBuilder msg(log_); |
1327 AppendCodeCreateHeader(&msg, tag, code); | 1218 AppendCodeCreateHeader(&msg, tag, code); |
1328 if (name->IsString()) { | 1219 if (name->IsString()) { |
1329 SmartArrayPointer<char> str = | 1220 SmartArrayPointer<char> str = |
(...skipping 11 matching lines...) Expand all Loading... |
1341 | 1232 |
1342 | 1233 |
1343 // Although, it is possible to extract source and line from | 1234 // Although, it is possible to extract source and line from |
1344 // the SharedFunctionInfo object, we left it to caller | 1235 // the SharedFunctionInfo object, we left it to caller |
1345 // to leave logging functions free from heap allocations. | 1236 // to leave logging functions free from heap allocations. |
1346 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1237 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
1347 Code* code, | 1238 Code* code, |
1348 SharedFunctionInfo* shared, | 1239 SharedFunctionInfo* shared, |
1349 CompilationInfo* info, | 1240 CompilationInfo* info, |
1350 Name* source, int line) { | 1241 Name* source, int line) { |
| 1242 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1243 |
1351 if (!is_logging_code_events()) return; | 1244 if (!is_logging_code_events()) return; |
1352 | 1245 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line)); |
1353 JIT_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
1354 LL_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
1355 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
1356 | 1246 |
1357 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1247 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1358 Log::MessageBuilder msg(log_); | 1248 Log::MessageBuilder msg(log_); |
1359 AppendCodeCreateHeader(&msg, tag, code); | 1249 AppendCodeCreateHeader(&msg, tag, code); |
1360 SmartArrayPointer<char> name = | 1250 SmartArrayPointer<char> name = |
1361 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1251 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
1362 msg.Append("\"%s ", *name); | 1252 msg.Append("\"%s ", *name); |
1363 if (source->IsString()) { | 1253 if (source->IsString()) { |
1364 SmartArrayPointer<char> sourcestr = | 1254 SmartArrayPointer<char> sourcestr = |
1365 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1255 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
1366 msg.Append("%s", *sourcestr); | 1256 msg.Append("%s", *sourcestr); |
1367 } else { | 1257 } else { |
1368 msg.AppendSymbolName(Symbol::cast(source)); | 1258 msg.AppendSymbolName(Symbol::cast(source)); |
1369 } | 1259 } |
1370 msg.Append(":%d\",", line); | 1260 msg.Append(":%d\",", line); |
1371 msg.AppendAddress(shared->address()); | 1261 msg.AppendAddress(shared->address()); |
1372 msg.Append(",%s", ComputeMarker(code)); | 1262 msg.Append(",%s", ComputeMarker(code)); |
1373 msg.Append('\n'); | 1263 msg.Append('\n'); |
1374 msg.WriteToLogFile(); | 1264 msg.WriteToLogFile(); |
1375 } | 1265 } |
1376 | 1266 |
1377 | 1267 |
1378 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1268 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
1379 Code* code, | 1269 Code* code, |
1380 int args_count) { | 1270 int args_count) { |
| 1271 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1272 |
1381 if (!is_logging_code_events()) return; | 1273 if (!is_logging_code_events()) return; |
1382 | 1274 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); |
1383 JIT_LOG(CodeCreateEvent(tag, code, args_count)); | |
1384 LL_LOG(CodeCreateEvent(tag, code, args_count)); | |
1385 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, args_count)); | |
1386 | 1275 |
1387 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1276 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1388 Log::MessageBuilder msg(log_); | 1277 Log::MessageBuilder msg(log_); |
1389 AppendCodeCreateHeader(&msg, tag, code); | 1278 AppendCodeCreateHeader(&msg, tag, code); |
1390 msg.Append("\"args_count: %d\"", args_count); | 1279 msg.Append("\"args_count: %d\"", args_count); |
1391 msg.Append('\n'); | 1280 msg.Append('\n'); |
1392 msg.WriteToLogFile(); | 1281 msg.WriteToLogFile(); |
1393 } | 1282 } |
1394 | 1283 |
1395 | 1284 |
1396 void Logger::CodeMovingGCEvent() { | 1285 void Logger::CodeMovingGCEvent() { |
| 1286 PROFILER_LOG(CodeMovingGCEvent()); |
| 1287 |
| 1288 if (!is_logging_code_events()) return; |
1397 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1289 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
1398 LL_LOG(CodeMovingGCEvent()); | 1290 CALL_LISTENERS(CodeMovingGCEvent()); |
1399 OS::SignalCodeMovingGC(); | 1291 OS::SignalCodeMovingGC(); |
1400 } | 1292 } |
1401 | 1293 |
1402 | 1294 |
1403 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1295 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 1296 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); |
| 1297 |
1404 if (!is_logging_code_events()) return; | 1298 if (!is_logging_code_events()) return; |
1405 | 1299 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); |
1406 JIT_LOG(RegExpCodeCreateEvent(code, source)); | |
1407 LL_LOG(RegExpCodeCreateEvent(code, source)); | |
1408 CODE_ADDRESS_MAP_LOG(RegExpCodeCreateEvent(code, source)); | |
1409 | 1300 |
1410 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1301 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1411 Log::MessageBuilder msg(log_); | 1302 Log::MessageBuilder msg(log_); |
1412 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1303 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
1413 msg.Append('"'); | 1304 msg.Append('"'); |
1414 msg.AppendDetailed(source, false); | 1305 msg.AppendDetailed(source, false); |
1415 msg.Append('"'); | 1306 msg.Append('"'); |
1416 msg.Append('\n'); | 1307 msg.Append('\n'); |
1417 msg.WriteToLogFile(); | 1308 msg.WriteToLogFile(); |
1418 } | 1309 } |
1419 | 1310 |
1420 | 1311 |
1421 void Logger::CodeMoveEvent(Address from, Address to) { | 1312 void Logger::CodeMoveEvent(Address from, Address to) { |
1422 JIT_LOG(CodeMovedEvent(from, to)); | 1313 PROFILER_LOG(CodeMoveEvent(from, to)); |
1423 if (!log_->IsEnabled()) return; | 1314 |
1424 LL_LOG(CodeMoveEvent(from, to)); | 1315 if (!is_logging_code_events()) return; |
1425 CODE_ADDRESS_MAP_LOG(CodeMoveEvent(from, to)); | 1316 CALL_LISTENERS(CodeMoveEvent(from, to)); |
1426 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1317 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
1427 } | 1318 } |
1428 | 1319 |
1429 | 1320 |
1430 void Logger::CodeDeleteEvent(Address from) { | 1321 void Logger::CodeDeleteEvent(Address from) { |
1431 JIT_LOG(CodeDeleteEvent(from)); | 1322 PROFILER_LOG(CodeDeleteEvent(from)); |
1432 if (!log_->IsEnabled()) return; | |
1433 LL_LOG(CodeDeleteEvent(from)); | |
1434 CODE_ADDRESS_MAP_LOG(CodeDeleteEvent(from)); | |
1435 | 1323 |
1436 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1324 if (!is_logging_code_events()) return; |
| 1325 CALL_LISTENERS(CodeDeleteEvent(from)); |
| 1326 |
| 1327 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1437 Log::MessageBuilder msg(log_); | 1328 Log::MessageBuilder msg(log_); |
1438 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); | 1329 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); |
1439 msg.AppendAddress(from); | 1330 msg.AppendAddress(from); |
1440 msg.Append('\n'); | 1331 msg.Append('\n'); |
1441 msg.WriteToLogFile(); | 1332 msg.WriteToLogFile(); |
1442 } | 1333 } |
1443 | 1334 |
1444 | 1335 |
1445 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1336 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
1446 int pc_offset, | 1337 int pc_offset, |
(...skipping 21 matching lines...) Expand all Loading... |
1468 } | 1359 } |
1469 } | 1360 } |
1470 | 1361 |
1471 | 1362 |
1472 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | 1363 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, |
1473 void* jit_handler_data) { | 1364 void* jit_handler_data) { |
1474 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); | 1365 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
1475 } | 1366 } |
1476 | 1367 |
1477 | 1368 |
| 1369 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { |
| 1370 if (code_name == NULL) return; // Not a code object. |
| 1371 Log::MessageBuilder msg(log_); |
| 1372 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1373 msg.AppendDoubleQuotedString(code_name); |
| 1374 msg.Append("\n"); |
| 1375 msg.WriteToLogFile(); |
| 1376 } |
| 1377 |
| 1378 |
1478 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1379 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
1479 if (!log_->IsEnabled()) return; | 1380 if (!log_->IsEnabled()) return; |
1480 LL_LOG(SnapshotPositionEvent(addr, pos)); | 1381 LL_LOG(SnapshotPositionEvent(addr, pos)); |
1481 if (Serializer::enabled()) { | |
1482 const char* code_name = code_address_map_->Lookup(addr); | |
1483 if (code_name == NULL) return; // Not a code object. | |
1484 Log::MessageBuilder msg(log_); | |
1485 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | |
1486 msg.AppendDoubleQuotedString(code_name); | |
1487 msg.Append("\n"); | |
1488 msg.WriteToLogFile(); | |
1489 } | |
1490 if (!FLAG_log_snapshot_positions) return; | 1382 if (!FLAG_log_snapshot_positions) return; |
1491 Log::MessageBuilder msg(log_); | 1383 Log::MessageBuilder msg(log_); |
1492 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 1384 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
1493 msg.AppendAddress(addr); | 1385 msg.AppendAddress(addr); |
1494 msg.Append(",%d", pos); | 1386 msg.Append(",%d", pos); |
1495 msg.Append('\n'); | 1387 msg.Append('\n'); |
1496 msg.WriteToLogFile(); | 1388 msg.WriteToLogFile(); |
1497 } | 1389 } |
1498 | 1390 |
1499 | 1391 |
1500 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { | 1392 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { |
| 1393 PROFILER_LOG(SharedFunctionInfoMoveEvent(from, to)); |
| 1394 |
| 1395 if (!is_logging_code_events()) return; |
1501 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); | 1396 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); |
1502 } | 1397 } |
1503 | 1398 |
1504 | 1399 |
1505 void Logger::MoveEventInternal(LogEventsAndTags event, | 1400 void Logger::MoveEventInternal(LogEventsAndTags event, |
1506 Address from, | 1401 Address from, |
1507 Address to) { | 1402 Address to) { |
1508 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1403 if (!FLAG_log_code || !log_->IsEnabled()) return; |
1509 Log::MessageBuilder msg(log_); | 1404 Log::MessageBuilder msg(log_); |
1510 msg.Append("%s,", kLogEventsNames[event]); | 1405 msg.Append("%s,", kLogEventsNames[event]); |
1511 msg.AppendAddress(from); | 1406 msg.AppendAddress(from); |
1512 msg.Append(','); | 1407 msg.Append(','); |
1513 msg.AppendAddress(to); | 1408 msg.AppendAddress(to); |
1514 msg.Append('\n'); | 1409 msg.Append('\n'); |
1515 msg.WriteToLogFile(); | 1410 msg.WriteToLogFile(); |
1516 } | 1411 } |
1517 | 1412 |
1518 | 1413 |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 bool Logger::SetUp(Isolate* isolate) { | 1862 bool Logger::SetUp(Isolate* isolate) { |
1968 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. | 1863 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. |
1969 if (is_initialized_) return true; | 1864 if (is_initialized_) return true; |
1970 is_initialized_ = true; | 1865 is_initialized_ = true; |
1971 | 1866 |
1972 // --ll-prof implies --log-code and --log-snapshot-positions. | 1867 // --ll-prof implies --log-code and --log-snapshot-positions. |
1973 if (FLAG_ll_prof) { | 1868 if (FLAG_ll_prof) { |
1974 FLAG_log_snapshot_positions = true; | 1869 FLAG_log_snapshot_positions = true; |
1975 } | 1870 } |
1976 | 1871 |
1977 // --prof_lazy controls --log-code, implies --noprof_auto. | 1872 // --prof_lazy controls --log-code. |
1978 if (FLAG_prof_lazy) { | 1873 if (FLAG_prof_lazy) { |
1979 FLAG_log_code = false; | 1874 FLAG_log_code = false; |
1980 FLAG_prof_auto = false; | |
1981 } | 1875 } |
1982 | 1876 |
1983 SmartArrayPointer<const char> log_file_name = | 1877 SmartArrayPointer<const char> log_file_name = |
1984 PrepareLogFileName(FLAG_logfile); | 1878 PrepareLogFileName(FLAG_logfile); |
1985 log_->Initialize(*log_file_name); | 1879 log_->Initialize(*log_file_name); |
1986 | 1880 |
1987 if (FLAG_ll_prof) { | 1881 if (FLAG_ll_prof) { |
1988 ll_logger_ = new LowLevelLogger(*log_file_name); | 1882 ll_logger_ = new LowLevelLogger(*log_file_name); |
| 1883 addCodeEventListener(ll_logger_); |
1989 } | 1884 } |
1990 | 1885 |
1991 ticker_ = new Ticker(isolate, kSamplingIntervalMs); | 1886 ticker_ = new Ticker(isolate, kSamplingIntervalMs); |
1992 | 1887 |
1993 if (Log::InitLogAtStart()) { | 1888 if (Log::InitLogAtStart()) { |
1994 logging_nesting_ = 1; | 1889 logging_nesting_ = 1; |
1995 } | 1890 } |
1996 | 1891 |
1997 if (FLAG_prof) { | 1892 if (FLAG_prof) { |
1998 profiler_ = new Profiler(isolate); | 1893 profiler_ = new Profiler(isolate); |
1999 if (!FLAG_prof_auto) { | 1894 if (FLAG_prof_lazy) { |
2000 profiler_->pause(); | 1895 profiler_->pause(); |
2001 } else { | 1896 } else { |
2002 logging_nesting_ = 1; | 1897 logging_nesting_ = 1; |
2003 } | |
2004 if (!FLAG_prof_lazy) { | |
2005 profiler_->Engage(); | 1898 profiler_->Engage(); |
2006 } | 1899 } |
2007 } | 1900 } |
2008 | 1901 |
2009 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); | 1902 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); |
2010 | 1903 |
2011 return true; | 1904 return true; |
2012 } | 1905 } |
2013 | 1906 |
2014 | 1907 |
2015 void Logger::SetCodeEventHandler(uint32_t options, | 1908 void Logger::SetCodeEventHandler(uint32_t options, |
2016 JitCodeEventHandler event_handler) { | 1909 JitCodeEventHandler event_handler) { |
2017 if (jit_logger_) { | 1910 if (jit_logger_) { |
| 1911 removeCodeEventListener(jit_logger_); |
2018 delete jit_logger_; | 1912 delete jit_logger_; |
2019 jit_logger_ = NULL; | 1913 jit_logger_ = NULL; |
2020 } | 1914 } |
2021 | 1915 |
2022 if (event_handler) { | 1916 if (event_handler) { |
2023 jit_logger_ = new JitLogger(event_handler); | 1917 jit_logger_ = new JitLogger(event_handler); |
2024 } | 1918 addCodeEventListener(jit_logger_); |
2025 | 1919 if (options & kJitCodeEventEnumExisting) { |
2026 if (jit_logger_ != NULL && (options & kJitCodeEventEnumExisting)) { | 1920 HandleScope scope(isolate_); |
2027 HandleScope scope(isolate_); | 1921 LogCodeObjects(); |
2028 LogCodeObjects(); | 1922 LogCompiledFunctions(); |
2029 LogCompiledFunctions(); | 1923 } |
2030 } | 1924 } |
2031 } | 1925 } |
2032 | 1926 |
2033 | 1927 |
2034 Sampler* Logger::sampler() { | 1928 Sampler* Logger::sampler() { |
2035 return ticker_; | 1929 return ticker_; |
2036 } | 1930 } |
2037 | 1931 |
2038 | 1932 |
2039 FILE* Logger::TearDown() { | 1933 FILE* Logger::TearDown() { |
2040 if (!is_initialized_) return NULL; | 1934 if (!is_initialized_) return NULL; |
2041 is_initialized_ = false; | 1935 is_initialized_ = false; |
2042 | 1936 |
2043 // Stop the profiler before closing the file. | 1937 // Stop the profiler before closing the file. |
2044 if (profiler_ != NULL) { | 1938 if (profiler_ != NULL) { |
2045 profiler_->Disengage(); | 1939 profiler_->Disengage(); |
2046 delete profiler_; | 1940 delete profiler_; |
2047 profiler_ = NULL; | 1941 profiler_ = NULL; |
2048 } | 1942 } |
2049 | 1943 |
2050 delete ticker_; | 1944 delete ticker_; |
2051 ticker_ = NULL; | 1945 ticker_ = NULL; |
2052 | 1946 |
2053 if (ll_logger_) { | 1947 if (ll_logger_) { |
| 1948 removeCodeEventListener(ll_logger_); |
2054 delete ll_logger_; | 1949 delete ll_logger_; |
2055 ll_logger_ = NULL; | 1950 ll_logger_ = NULL; |
2056 } | 1951 } |
2057 | 1952 |
2058 if (jit_logger_) { | 1953 if (jit_logger_) { |
| 1954 removeCodeEventListener(jit_logger_); |
2059 delete jit_logger_; | 1955 delete jit_logger_; |
2060 jit_logger_ = NULL; | 1956 jit_logger_ = NULL; |
2061 } | 1957 } |
2062 | 1958 |
2063 return log_->Close(); | 1959 return log_->Close(); |
2064 } | 1960 } |
2065 | 1961 |
2066 } } // namespace v8::internal | 1962 } } // namespace v8::internal |
OLD | NEW |