Chromium Code Reviews| 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 29 matching lines...) Expand all Loading... | |
| 40 #include "platform.h" | 40 #include "platform.h" |
| 41 #include "runtime-profiler.h" | 41 #include "runtime-profiler.h" |
| 42 #include "serialize.h" | 42 #include "serialize.h" |
| 43 #include "string-stream.h" | 43 #include "string-stream.h" |
| 44 #include "vm-state-inl.h" | 44 #include "vm-state-inl.h" |
| 45 | 45 |
| 46 namespace v8 { | 46 namespace v8 { |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 | 49 |
| 50 #define DECLARE_EVENT(ignore1, name) name, | |
| 51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | |
| 52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | |
| 53 }; | |
| 54 #undef DECLARE_EVENT | |
| 55 | |
| 56 | |
| 57 class CodeEventLogger { | |
| 58 public: | |
| 59 virtual ~CodeEventLogger() { } | |
| 60 | |
| 61 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 62 Code* code, | |
| 63 const char* comment); | |
| 64 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 65 Code* code, | |
| 66 Name* name); | |
| 67 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 68 Code* code, | |
| 69 int args_count); | |
| 70 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 71 Code* code, | |
| 72 SharedFunctionInfo* shared, | |
| 73 CompilationInfo* info, | |
| 74 Name* name); | |
| 75 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 76 Code* code, | |
| 77 SharedFunctionInfo* shared, | |
| 78 CompilationInfo* info, | |
| 79 Name* source, | |
| 80 int line); | |
| 81 void RegExpCodeCreateEvent(Code* code, String* source); | |
| 82 | |
| 83 class NameBuffer { | |
|
yurys
2013/07/19 12:30:34
Should be protected in CodeEventLogger?
| |
| 84 public: | |
| 85 NameBuffer() { Reset(); } | |
| 86 | |
| 87 void Reset() { | |
| 88 utf8_pos_ = 0; | |
| 89 } | |
| 90 | |
| 91 void Init(Logger::LogEventsAndTags tag) { | |
| 92 Reset(); | |
| 93 AppendBytes(kLogEventsNames[tag]); | |
| 94 AppendByte(':'); | |
| 95 } | |
| 96 | |
| 97 void AppendName(Name* name) { | |
| 98 if (name->IsString()) { | |
| 99 AppendString(String::cast(name)); | |
| 100 } else { | |
| 101 Symbol* symbol = Symbol::cast(name); | |
| 102 AppendBytes("symbol("); | |
| 103 if (!symbol->name()->IsUndefined()) { | |
| 104 AppendBytes("\""); | |
| 105 AppendString(String::cast(symbol->name())); | |
| 106 AppendBytes("\" "); | |
| 107 } | |
| 108 AppendBytes("hash "); | |
| 109 AppendHex(symbol->Hash()); | |
| 110 AppendByte(')'); | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 void AppendString(String* str) { | |
| 115 if (str == NULL) return; | |
| 116 int uc16_length = Min(str->length(), kUtf16BufferSize); | |
| 117 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); | |
| 118 int previous = unibrow::Utf16::kNoPreviousCharacter; | |
| 119 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
| 120 uc16 c = utf16_buffer[i]; | |
| 121 if (c <= unibrow::Utf8::kMaxOneByteChar) { | |
| 122 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); | |
| 123 } else { | |
| 124 int char_length = unibrow::Utf8::Length(c, previous); | |
| 125 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
| 126 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); | |
| 127 utf8_pos_ += char_length; | |
| 128 } | |
| 129 previous = c; | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 void AppendBytes(const char* bytes, int size) { | |
| 134 size = Min(size, kUtf8BufferSize - utf8_pos_); | |
| 135 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); | |
| 136 utf8_pos_ += size; | |
| 137 } | |
| 138 | |
| 139 void AppendBytes(const char* bytes) { | |
| 140 AppendBytes(bytes, StrLength(bytes)); | |
| 141 } | |
| 142 | |
| 143 void AppendByte(char c) { | |
| 144 if (utf8_pos_ >= kUtf8BufferSize) return; | |
| 145 utf8_buffer_[utf8_pos_++] = c; | |
| 146 } | |
| 147 | |
| 148 void AppendInt(int n) { | |
| 149 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
| 150 kUtf8BufferSize - utf8_pos_); | |
| 151 int size = OS::SNPrintF(buffer, "%d", n); | |
| 152 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 153 utf8_pos_ += size; | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 void AppendHex(uint32_t n) { | |
| 158 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
| 159 kUtf8BufferSize - utf8_pos_); | |
| 160 int size = OS::SNPrintF(buffer, "%x", n); | |
| 161 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 162 utf8_pos_ += size; | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 const char* get() { return utf8_buffer_; } | |
| 167 int size() const { return utf8_pos_; } | |
| 168 | |
| 169 private: | |
| 170 static const int kUtf8BufferSize = 512; | |
| 171 static const int kUtf16BufferSize = 128; | |
| 172 | |
| 173 int utf8_pos_; | |
| 174 char utf8_buffer_[kUtf8BufferSize]; | |
| 175 uc16 utf16_buffer[kUtf16BufferSize]; | |
| 176 }; | |
| 177 | |
| 178 private: | |
| 179 virtual void LogRecordedBuffer(Code* code, | |
| 180 SharedFunctionInfo* shared, | |
| 181 NameBuffer* name_buffer) = 0; | |
| 182 | |
| 183 NameBuffer name_buffer_; | |
|
yurys
2013/07/19 12:30:34
Now there is a separate instance of NameBuffer in
| |
| 184 }; | |
| 185 | |
| 186 | |
| 50 // Low-level logging support. | 187 // Low-level logging support. |
| 51 class LowLevelLogger { | 188 class LowLevelLogger : public CodeEventLogger { |
| 52 public: | 189 public: |
| 53 explicit LowLevelLogger(const char* file_name); | 190 explicit LowLevelLogger(const char* file_name); |
| 54 ~LowLevelLogger(); | 191 virtual ~LowLevelLogger(); |
| 55 | 192 |
| 56 void CodeCreateEvent(Code* code, const char* name, int name_size); | |
| 57 void CodeMoveEvent(Address from, Address to); | 193 void CodeMoveEvent(Address from, Address to); |
| 58 void CodeDeleteEvent(Address from); | 194 void CodeDeleteEvent(Address from); |
| 59 void SnapshotPositionEvent(Address addr, int pos); | 195 void SnapshotPositionEvent(Address addr, int pos); |
| 60 void CodeMovingGCEvent(); | 196 void CodeMovingGCEvent(); |
| 61 | 197 |
| 62 private: | 198 private: |
| 199 virtual void LogRecordedBuffer(Code* code, | |
| 200 SharedFunctionInfo* shared, | |
| 201 NameBuffer* name_buffer); | |
| 202 | |
| 63 // Low-level profiling event structures. | 203 // Low-level profiling event structures. |
| 64 | |
| 65 struct CodeCreateStruct { | 204 struct CodeCreateStruct { |
| 66 static const char kTag = 'C'; | 205 static const char kTag = 'C'; |
| 67 | 206 |
| 68 int32_t name_size; | 207 int32_t name_size; |
| 69 Address code_address; | 208 Address code_address; |
| 70 int32_t code_size; | 209 int32_t code_size; |
| 71 }; | 210 }; |
| 72 | 211 |
| 73 | 212 |
| 74 struct CodeMoveStruct { | 213 struct CodeMoveStruct { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 } | 254 } |
| 116 | 255 |
| 117 FILE* ll_output_handle_; | 256 FILE* ll_output_handle_; |
| 118 }; | 257 }; |
| 119 | 258 |
| 120 const char LowLevelLogger::kLogExt[] = ".ll"; | 259 const char LowLevelLogger::kLogExt[] = ".ll"; |
| 121 | 260 |
| 122 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 261 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 123 | 262 |
| 124 | 263 |
| 264 class CodeAddressMap: public CodeEventLogger { | |
| 265 public: | |
| 266 CodeAddressMap() { } | |
| 267 virtual ~CodeAddressMap() { } | |
| 268 | |
| 269 void CodeMoveEvent(Address from, Address to) { | |
| 270 address_to_name_map_.Move(from, to); | |
| 271 } | |
| 272 | |
| 273 void CodeDeleteEvent(Address from) { | |
| 274 address_to_name_map_.Remove(from); | |
| 275 } | |
| 276 | |
| 277 const char* Lookup(Address address) { | |
| 278 return address_to_name_map_.Lookup(address); | |
| 279 } | |
| 280 | |
| 281 private: | |
| 282 class NameMap { | |
| 283 public: | |
| 284 NameMap() : impl_(&PointerEquals) {} | |
| 285 | |
| 286 ~NameMap() { | |
| 287 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | |
| 288 DeleteArray(static_cast<const char*>(p->value)); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 void Insert(Address code_address, const char* name, int name_size) { | |
| 293 HashMap::Entry* entry = FindOrCreateEntry(code_address); | |
| 294 if (entry->value == NULL) { | |
| 295 entry->value = CopyName(name, name_size); | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 const char* Lookup(Address code_address) { | |
| 300 HashMap::Entry* entry = FindEntry(code_address); | |
| 301 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; | |
| 302 } | |
| 303 | |
| 304 void Remove(Address code_address) { | |
| 305 HashMap::Entry* entry = FindEntry(code_address); | |
| 306 if (entry != NULL) { | |
| 307 DeleteArray(static_cast<char*>(entry->value)); | |
| 308 RemoveEntry(entry); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 void Move(Address from, Address to) { | |
| 313 if (from == to) return; | |
| 314 HashMap::Entry* from_entry = FindEntry(from); | |
| 315 ASSERT(from_entry != NULL); | |
| 316 void* value = from_entry->value; | |
| 317 RemoveEntry(from_entry); | |
| 318 HashMap::Entry* to_entry = FindOrCreateEntry(to); | |
| 319 ASSERT(to_entry->value == NULL); | |
| 320 to_entry->value = value; | |
| 321 } | |
| 322 | |
| 323 private: | |
| 324 static bool PointerEquals(void* lhs, void* rhs) { | |
| 325 return lhs == rhs; | |
| 326 } | |
| 327 | |
| 328 static char* CopyName(const char* name, int name_size) { | |
| 329 char* result = NewArray<char>(name_size + 1); | |
| 330 for (int i = 0; i < name_size; ++i) { | |
| 331 char c = name[i]; | |
| 332 if (c == '\0') c = ' '; | |
| 333 result[i] = c; | |
| 334 } | |
| 335 result[name_size] = '\0'; | |
| 336 return result; | |
| 337 } | |
| 338 | |
| 339 HashMap::Entry* FindOrCreateEntry(Address code_address) { | |
| 340 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); | |
| 341 } | |
| 342 | |
| 343 HashMap::Entry* FindEntry(Address code_address) { | |
| 344 return impl_.Lookup(code_address, | |
| 345 ComputePointerHash(code_address), | |
| 346 false); | |
| 347 } | |
| 348 | |
| 349 void RemoveEntry(HashMap::Entry* entry) { | |
| 350 impl_.Remove(entry->key, entry->hash); | |
| 351 } | |
| 352 | |
| 353 HashMap impl_; | |
| 354 | |
| 355 DISALLOW_COPY_AND_ASSIGN(NameMap); | |
| 356 }; | |
| 357 | |
| 358 virtual void LogRecordedBuffer(Code* code, | |
| 359 SharedFunctionInfo*, | |
| 360 NameBuffer* name_buffer) { | |
| 361 address_to_name_map_.Insert(code->address(), | |
| 362 name_buffer->get(), | |
| 363 name_buffer->size()); | |
| 364 } | |
| 365 | |
| 366 NameMap address_to_name_map_; | |
| 367 }; | |
| 368 | |
| 369 | |
| 370 #define CODE_ADDRESS_MAP(Call)\ | |
|
yurys
2013/07/19 12:30:34
CODE_ADDRESS_MAP_LOG?
| |
| 371 if (Serializer::enabled()) code_address_map_->Call; | |
| 372 | |
| 373 | |
| 125 // The Profiler samples pc and sp values for the main thread. | 374 // The Profiler samples pc and sp values for the main thread. |
| 126 // Each sample is appended to a circular buffer. | 375 // Each sample is appended to a circular buffer. |
| 127 // An independent thread removes data and writes it to the log. | 376 // An independent thread removes data and writes it to the log. |
| 128 // This design minimizes the time spent in the sampler. | 377 // This design minimizes the time spent in the sampler. |
| 129 // | 378 // |
| 130 class Profiler: public Thread { | 379 class Profiler: public Thread { |
| 131 public: | 380 public: |
| 132 explicit Profiler(Isolate* isolate); | 381 explicit Profiler(Isolate* isolate); |
| 133 void Engage(); | 382 void Engage(); |
| 134 void Disengage(); | 383 void Disengage(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 LOG(isolate_, TickEvent(&sample, overflow)); | 533 LOG(isolate_, TickEvent(&sample, overflow)); |
| 285 overflow = Remove(&sample); | 534 overflow = Remove(&sample); |
| 286 } | 535 } |
| 287 } | 536 } |
| 288 | 537 |
| 289 | 538 |
| 290 // | 539 // |
| 291 // Logger class implementation. | 540 // Logger class implementation. |
| 292 // | 541 // |
| 293 | 542 |
| 294 class Logger::NameMap { | |
| 295 public: | |
| 296 NameMap() : impl_(&PointerEquals) {} | |
| 297 | |
| 298 ~NameMap() { | |
| 299 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | |
| 300 DeleteArray(static_cast<const char*>(p->value)); | |
| 301 } | |
| 302 } | |
| 303 | |
| 304 void Insert(Address code_address, const char* name, int name_size) { | |
| 305 HashMap::Entry* entry = FindOrCreateEntry(code_address); | |
| 306 if (entry->value == NULL) { | |
| 307 entry->value = CopyName(name, name_size); | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 const char* Lookup(Address code_address) { | |
| 312 HashMap::Entry* entry = FindEntry(code_address); | |
| 313 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; | |
| 314 } | |
| 315 | |
| 316 void Remove(Address code_address) { | |
| 317 HashMap::Entry* entry = FindEntry(code_address); | |
| 318 if (entry != NULL) { | |
| 319 DeleteArray(static_cast<char*>(entry->value)); | |
| 320 RemoveEntry(entry); | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 void Move(Address from, Address to) { | |
| 325 if (from == to) return; | |
| 326 HashMap::Entry* from_entry = FindEntry(from); | |
| 327 ASSERT(from_entry != NULL); | |
| 328 void* value = from_entry->value; | |
| 329 RemoveEntry(from_entry); | |
| 330 HashMap::Entry* to_entry = FindOrCreateEntry(to); | |
| 331 ASSERT(to_entry->value == NULL); | |
| 332 to_entry->value = value; | |
| 333 } | |
| 334 | |
| 335 private: | |
| 336 static bool PointerEquals(void* lhs, void* rhs) { | |
| 337 return lhs == rhs; | |
| 338 } | |
| 339 | |
| 340 static char* CopyName(const char* name, int name_size) { | |
| 341 char* result = NewArray<char>(name_size + 1); | |
| 342 for (int i = 0; i < name_size; ++i) { | |
| 343 char c = name[i]; | |
| 344 if (c == '\0') c = ' '; | |
| 345 result[i] = c; | |
| 346 } | |
| 347 result[name_size] = '\0'; | |
| 348 return result; | |
| 349 } | |
| 350 | |
| 351 HashMap::Entry* FindOrCreateEntry(Address code_address) { | |
| 352 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); | |
| 353 } | |
| 354 | |
| 355 HashMap::Entry* FindEntry(Address code_address) { | |
| 356 return impl_.Lookup(code_address, ComputePointerHash(code_address), false); | |
| 357 } | |
| 358 | |
| 359 void RemoveEntry(HashMap::Entry* entry) { | |
| 360 impl_.Remove(entry->key, entry->hash); | |
| 361 } | |
| 362 | |
| 363 HashMap impl_; | |
| 364 | |
| 365 DISALLOW_COPY_AND_ASSIGN(NameMap); | |
| 366 }; | |
| 367 | |
| 368 | |
| 369 class Logger::NameBuffer { | |
| 370 public: | |
| 371 NameBuffer() { Reset(); } | |
| 372 | |
| 373 void Reset() { | |
| 374 utf8_pos_ = 0; | |
| 375 } | |
| 376 | |
| 377 void AppendString(String* str) { | |
| 378 if (str == NULL) return; | |
| 379 int uc16_length = Min(str->length(), kUtf16BufferSize); | |
| 380 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); | |
| 381 int previous = unibrow::Utf16::kNoPreviousCharacter; | |
| 382 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
| 383 uc16 c = utf16_buffer[i]; | |
| 384 if (c <= unibrow::Utf8::kMaxOneByteChar) { | |
| 385 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); | |
| 386 } else { | |
| 387 int char_length = unibrow::Utf8::Length(c, previous); | |
| 388 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
| 389 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); | |
| 390 utf8_pos_ += char_length; | |
| 391 } | |
| 392 previous = c; | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 void AppendBytes(const char* bytes, int size) { | |
| 397 size = Min(size, kUtf8BufferSize - utf8_pos_); | |
| 398 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); | |
| 399 utf8_pos_ += size; | |
| 400 } | |
| 401 | |
| 402 void AppendBytes(const char* bytes) { | |
| 403 AppendBytes(bytes, StrLength(bytes)); | |
| 404 } | |
| 405 | |
| 406 void AppendByte(char c) { | |
| 407 if (utf8_pos_ >= kUtf8BufferSize) return; | |
| 408 utf8_buffer_[utf8_pos_++] = c; | |
| 409 } | |
| 410 | |
| 411 void AppendInt(int n) { | |
| 412 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); | |
| 413 int size = OS::SNPrintF(buffer, "%d", n); | |
| 414 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 415 utf8_pos_ += size; | |
| 416 } | |
| 417 } | |
| 418 | |
| 419 void AppendHex(uint32_t n) { | |
| 420 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); | |
| 421 int size = OS::SNPrintF(buffer, "%x", n); | |
| 422 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 423 utf8_pos_ += size; | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 const char* get() { return utf8_buffer_; } | |
| 428 int size() const { return utf8_pos_; } | |
| 429 | |
| 430 private: | |
| 431 static const int kUtf8BufferSize = 512; | |
| 432 static const int kUtf16BufferSize = 128; | |
| 433 | |
| 434 int utf8_pos_; | |
| 435 char utf8_buffer_[kUtf8BufferSize]; | |
| 436 uc16 utf16_buffer[kUtf16BufferSize]; | |
| 437 }; | |
| 438 | |
| 439 | |
| 440 Logger::Logger(Isolate* isolate) | 543 Logger::Logger(Isolate* isolate) |
| 441 : isolate_(isolate), | 544 : isolate_(isolate), |
| 442 ticker_(NULL), | 545 ticker_(NULL), |
| 443 profiler_(NULL), | 546 profiler_(NULL), |
| 444 log_events_(NULL), | 547 log_events_(NULL), |
| 445 logging_nesting_(0), | 548 logging_nesting_(0), |
| 446 cpu_profiler_nesting_(0), | 549 cpu_profiler_nesting_(0), |
| 447 log_(new Log(this)), | 550 log_(new Log(this)), |
| 448 ll_logger_(NULL), | 551 ll_logger_(NULL), |
| 449 jit_logger_(NULL), | 552 jit_logger_(NULL), |
| 450 name_buffer_(new NameBuffer), | 553 code_address_map_(new CodeAddressMap), |
| 451 address_to_name_map_(NULL), | |
| 452 is_initialized_(false), | 554 is_initialized_(false), |
| 453 last_address_(NULL), | 555 last_address_(NULL), |
| 454 prev_sp_(NULL), | 556 prev_sp_(NULL), |
| 455 prev_function_(NULL), | 557 prev_function_(NULL), |
| 456 prev_to_(NULL), | 558 prev_to_(NULL), |
| 457 prev_code_(NULL), | 559 prev_code_(NULL), |
| 458 epoch_(0) { | 560 epoch_(0) { |
| 459 } | 561 } |
| 460 | 562 |
| 461 | 563 |
| 462 Logger::~Logger() { | 564 Logger::~Logger() { |
| 463 delete address_to_name_map_; | 565 delete code_address_map_; |
| 464 delete name_buffer_; | |
| 465 delete log_; | 566 delete log_; |
| 466 } | 567 } |
| 467 | 568 |
| 468 | 569 |
| 469 class JitLogger { | 570 class JitLogger : public CodeEventLogger { |
| 470 public: | 571 public: |
| 471 explicit JitLogger(JitCodeEventHandler code_event_handler); | 572 explicit JitLogger(JitCodeEventHandler code_event_handler); |
| 472 | 573 |
| 473 void CodeCreateEvent(Code* code, Script* script, | |
| 474 const char* name, size_t name_len); | |
| 475 void CodeMovedEvent(Address from, Address to); | 574 void CodeMovedEvent(Address from, Address to); |
| 476 void CodeRemovedEvent(Address from); | 575 void CodeDeleteEvent(Address from); |
| 477 void AddCodeLinePosInfoEvent( | 576 void AddCodeLinePosInfoEvent( |
| 478 void* jit_handler_data, | 577 void* jit_handler_data, |
| 479 int pc_offset, | 578 int pc_offset, |
| 480 int position, | 579 int position, |
| 481 JitCodeEvent::PositionType position_type); | 580 JitCodeEvent::PositionType position_type); |
| 482 void* StartCodePosInfoEvent(); | 581 void* StartCodePosInfoEvent(); |
| 483 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); | 582 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); |
| 484 | 583 |
| 485 private: | 584 private: |
| 585 virtual void LogRecordedBuffer(Code* code, | |
| 586 SharedFunctionInfo* shared, | |
| 587 CodeEventLogger::NameBuffer* name_buffer); | |
| 588 | |
| 486 JitCodeEventHandler code_event_handler_; | 589 JitCodeEventHandler code_event_handler_; |
| 487 }; | 590 }; |
| 488 | 591 |
| 489 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; | 592 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
| 490 | 593 |
| 491 | 594 |
| 492 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) | 595 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
| 493 : code_event_handler_(code_event_handler) { | 596 : code_event_handler_(code_event_handler) { |
| 494 } | 597 } |
| 495 | 598 |
| 496 | 599 |
| 497 void JitLogger::CodeCreateEvent(Code* code, | 600 void JitLogger::LogRecordedBuffer(Code* code, |
| 498 Script* script, | 601 SharedFunctionInfo* shared, |
| 499 const char* name, | 602 CodeEventLogger::NameBuffer* name_buffer) { |
| 500 size_t name_len) { | |
| 501 JitCodeEvent event; | 603 JitCodeEvent event; |
| 502 memset(&event, 0, sizeof(event)); | 604 memset(&event, 0, sizeof(event)); |
| 503 event.type = JitCodeEvent::CODE_ADDED; | 605 event.type = JitCodeEvent::CODE_ADDED; |
| 504 event.code_start = code->instruction_start(); | 606 event.code_start = code->instruction_start(); |
| 505 event.code_len = code->instruction_size(); | 607 event.code_len = code->instruction_size(); |
| 506 Handle<Script> script_handle = | 608 Handle<Script> script_handle; |
| 507 script != NULL ? Handle<Script>(script) : Handle<Script>(); | 609 if (shared && shared->script()->IsScript()) { |
| 610 script_handle = Handle<Script>(Script::cast(shared->script())); | |
| 611 } | |
| 508 event.script = ToApiHandle<v8::Script>(script_handle); | 612 event.script = ToApiHandle<v8::Script>(script_handle); |
| 509 event.name.str = name; | 613 event.name.str = name_buffer->get(); |
| 510 event.name.len = name_len; | 614 event.name.len = name_buffer->size(); |
| 511 | |
| 512 code_event_handler_(&event); | 615 code_event_handler_(&event); |
| 513 } | 616 } |
| 514 | 617 |
| 515 | 618 |
| 516 void JitLogger::CodeMovedEvent(Address from, Address to) { | 619 void JitLogger::CodeMovedEvent(Address from, Address to) { |
| 517 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | 620 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
| 518 | 621 |
| 519 JitCodeEvent event; | 622 JitCodeEvent event; |
| 520 event.type = JitCodeEvent::CODE_MOVED; | 623 event.type = JitCodeEvent::CODE_MOVED; |
| 521 event.code_start = from_code->instruction_start(); | 624 event.code_start = from_code->instruction_start(); |
| 522 event.code_len = from_code->instruction_size(); | 625 event.code_len = from_code->instruction_size(); |
| 523 | 626 |
| 524 // Calculate the header size. | 627 // Calculate the header size. |
| 525 const size_t header_size = | 628 const size_t header_size = |
| 526 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | 629 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); |
| 527 | 630 |
| 528 // Calculate the new start address of the instructions. | 631 // Calculate the new start address of the instructions. |
| 529 event.new_code_start = | 632 event.new_code_start = |
| 530 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; | 633 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; |
| 531 | 634 |
| 532 code_event_handler_(&event); | 635 code_event_handler_(&event); |
| 533 } | 636 } |
| 534 | 637 |
| 535 | 638 |
| 536 void JitLogger::CodeRemovedEvent(Address from) { | 639 void JitLogger::CodeDeleteEvent(Address from) { |
| 537 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | 640 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
| 538 | 641 |
| 539 JitCodeEvent event; | 642 JitCodeEvent event; |
| 540 event.type = JitCodeEvent::CODE_REMOVED; | 643 event.type = JitCodeEvent::CODE_REMOVED; |
| 541 event.code_start = from_code->instruction_start(); | 644 event.code_start = from_code->instruction_start(); |
| 542 event.code_len = from_code->instruction_size(); | 645 event.code_len = from_code->instruction_size(); |
| 543 | 646 |
| 544 code_event_handler_(&event); | 647 code_event_handler_(&event); |
| 545 } | 648 } |
| 546 | 649 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 574 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) { | 677 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) { |
| 575 JitCodeEvent event; | 678 JitCodeEvent event; |
| 576 memset(&event, 0, sizeof(event)); | 679 memset(&event, 0, sizeof(event)); |
| 577 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; | 680 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; |
| 578 event.code_start = code->instruction_start(); | 681 event.code_start = code->instruction_start(); |
| 579 event.user_data = jit_handler_data; | 682 event.user_data = jit_handler_data; |
| 580 | 683 |
| 581 code_event_handler_(&event); | 684 code_event_handler_(&event); |
| 582 } | 685 } |
| 583 | 686 |
| 584 #define DECLARE_EVENT(ignore1, name) name, | |
| 585 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | |
| 586 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | |
| 587 }; | |
| 588 #undef DECLARE_EVENT | |
| 589 | |
| 590 | 687 |
| 591 void Logger::ProfilerBeginEvent() { | 688 void Logger::ProfilerBeginEvent() { |
| 592 if (!log_->IsEnabled()) return; | 689 if (!log_->IsEnabled()) return; |
| 593 Log::MessageBuilder msg(log_); | 690 Log::MessageBuilder msg(log_); |
| 594 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); | 691 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); |
| 595 msg.WriteToLogFile(); | 692 msg.WriteToLogFile(); |
| 596 } | 693 } |
| 597 | 694 |
| 598 | 695 |
| 599 void Logger::StringEvent(const char* name, const char* value) { | 696 void Logger::StringEvent(const char* name, const char* value) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 980 CallbackEventInternal("get ", name, entry_point); | 1077 CallbackEventInternal("get ", name, entry_point); |
| 981 } | 1078 } |
| 982 | 1079 |
| 983 | 1080 |
| 984 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1081 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
| 985 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1082 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 986 CallbackEventInternal("set ", name, entry_point); | 1083 CallbackEventInternal("set ", name, entry_point); |
| 987 } | 1084 } |
| 988 | 1085 |
| 989 | 1086 |
| 990 void Logger::AppendName(Name* name) { | |
| 991 if (name->IsString()) { | |
| 992 name_buffer_->AppendString(String::cast(name)); | |
| 993 } else { | |
| 994 Symbol* symbol = Symbol::cast(name); | |
| 995 name_buffer_->AppendBytes("symbol("); | |
| 996 if (!symbol->name()->IsUndefined()) { | |
| 997 name_buffer_->AppendBytes("\""); | |
| 998 name_buffer_->AppendString(String::cast(symbol->name())); | |
| 999 name_buffer_->AppendBytes("\" "); | |
| 1000 } | |
| 1001 name_buffer_->AppendBytes("hash "); | |
| 1002 name_buffer_->AppendHex(symbol->Hash()); | |
| 1003 name_buffer_->AppendByte(')'); | |
| 1004 } | |
| 1005 } | |
| 1006 | |
| 1007 | |
| 1008 void Logger::InitNameBuffer(LogEventsAndTags tag) { | |
| 1009 name_buffer_->Reset(); | |
| 1010 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 1011 name_buffer_->AppendByte(':'); | |
| 1012 } | |
| 1013 | |
| 1014 | |
| 1015 void Logger::LogRecordedBuffer(Code* code, SharedFunctionInfo* shared) { | |
| 1016 Script* script = shared && shared->script()->IsScript() ? | |
| 1017 Script::cast(shared->script()) : NULL; | |
| 1018 JIT_LOG(CodeCreateEvent(code, script, name_buffer_->get(), | |
| 1019 name_buffer_->size())); | |
| 1020 if (!log_->IsEnabled()) return; | |
| 1021 LL_LOG(CodeCreateEvent(code, name_buffer_->get(), name_buffer_->size())); | |
| 1022 if (Serializer::enabled()) { | |
| 1023 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 1024 } | |
| 1025 } | |
| 1026 | |
| 1027 | |
| 1028 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, | 1087 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
| 1029 Logger::LogEventsAndTags tag, | 1088 Logger::LogEventsAndTags tag, |
| 1030 Code* code) { | 1089 Code* code) { |
| 1031 ASSERT(msg); | 1090 ASSERT(msg); |
| 1032 msg->Append("%s,%s,%d,", | 1091 msg->Append("%s,%s,%d,", |
| 1033 kLogEventsNames[Logger::CODE_CREATION_EVENT], | 1092 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
| 1034 kLogEventsNames[tag], | 1093 kLogEventsNames[tag], |
| 1035 code->kind()); | 1094 code->kind()); |
| 1036 msg->AppendAddress(code->address()); | 1095 msg->AppendAddress(code->address()); |
| 1037 msg->Append(",%d,", code->ExecutableSize()); | 1096 msg->Append(",%d,", code->ExecutableSize()); |
| 1038 } | 1097 } |
| 1039 | 1098 |
| 1040 | 1099 |
| 1100 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 1101 Code* code, | |
| 1102 const char* comment) { | |
| 1103 name_buffer_.Init(tag); | |
| 1104 name_buffer_.AppendBytes(comment); | |
| 1105 LogRecordedBuffer(code, NULL, &name_buffer_); | |
| 1106 } | |
| 1107 | |
| 1108 | |
| 1041 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1109 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1042 Code* code, | 1110 Code* code, |
| 1043 const char* comment) { | 1111 const char* comment) { |
| 1044 if (!is_logging_code_events()) return; | 1112 if (!is_logging_code_events()) return; |
| 1045 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1113 |
| 1046 InitNameBuffer(tag); | 1114 JIT_LOG(CodeCreateEvent(tag, code, comment)); |
| 1047 name_buffer_->AppendBytes(comment); | 1115 LL_LOG(CodeCreateEvent(tag, code, comment)); |
| 1048 LogRecordedBuffer(code, NULL); | 1116 CODE_ADDRESS_MAP(CodeCreateEvent(tag, code, comment)); |
| 1049 } | |
| 1050 | 1117 |
| 1051 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1118 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1052 Log::MessageBuilder msg(log_); | 1119 Log::MessageBuilder msg(log_); |
| 1053 AppendCodeCreateHeader(&msg, tag, code); | 1120 AppendCodeCreateHeader(&msg, tag, code); |
| 1054 msg.AppendDoubleQuotedString(comment); | 1121 msg.AppendDoubleQuotedString(comment); |
| 1055 msg.Append('\n'); | 1122 msg.Append('\n'); |
| 1056 msg.WriteToLogFile(); | 1123 msg.WriteToLogFile(); |
| 1057 } | 1124 } |
| 1058 | 1125 |
| 1059 | 1126 |
| 1127 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 1128 Code* code, | |
| 1129 Name* name) { | |
| 1130 name_buffer_.Init(tag); | |
| 1131 name_buffer_.AppendName(name); | |
| 1132 LogRecordedBuffer(code, NULL, &name_buffer_); | |
| 1133 } | |
| 1134 | |
| 1135 | |
| 1060 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1136 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1061 Code* code, | 1137 Code* code, |
| 1062 Name* name) { | 1138 Name* name) { |
| 1063 if (!is_logging_code_events()) return; | 1139 if (!is_logging_code_events()) return; |
| 1064 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1140 |
| 1065 InitNameBuffer(tag); | 1141 JIT_LOG(CodeCreateEvent(tag, code, name)); |
| 1066 AppendName(name); | 1142 LL_LOG(CodeCreateEvent(tag, code, name)); |
| 1067 LogRecordedBuffer(code, NULL); | 1143 CODE_ADDRESS_MAP(CodeCreateEvent(tag, code, name)); |
| 1068 } | |
| 1069 | 1144 |
| 1070 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1145 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1071 Log::MessageBuilder msg(log_); | 1146 Log::MessageBuilder msg(log_); |
| 1072 AppendCodeCreateHeader(&msg, tag, code); | 1147 AppendCodeCreateHeader(&msg, tag, code); |
| 1073 if (name->IsString()) { | 1148 if (name->IsString()) { |
| 1074 msg.Append('"'); | 1149 msg.Append('"'); |
| 1075 msg.AppendDetailed(String::cast(name), false); | 1150 msg.AppendDetailed(String::cast(name), false); |
| 1076 msg.Append('"'); | 1151 msg.Append('"'); |
| 1077 } else { | 1152 } else { |
| 1078 msg.AppendSymbolName(Symbol::cast(name)); | 1153 msg.AppendSymbolName(Symbol::cast(name)); |
| 1079 } | 1154 } |
| 1080 msg.Append('\n'); | 1155 msg.Append('\n'); |
| 1081 msg.WriteToLogFile(); | 1156 msg.WriteToLogFile(); |
| 1082 } | 1157 } |
| 1083 | 1158 |
| 1084 | 1159 |
| 1085 // ComputeMarker must only be used when SharedFunctionInfo is known. | 1160 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 1086 static const char* ComputeMarker(Code* code) { | 1161 static const char* ComputeMarker(Code* code) { |
| 1087 switch (code->kind()) { | 1162 switch (code->kind()) { |
| 1088 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | 1163 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 1089 case Code::OPTIMIZED_FUNCTION: return "*"; | 1164 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 1090 default: return ""; | 1165 default: return ""; |
| 1091 } | 1166 } |
| 1092 } | 1167 } |
| 1093 | 1168 |
| 1094 | 1169 |
| 1170 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 1171 Code* code, | |
| 1172 SharedFunctionInfo* shared, | |
| 1173 CompilationInfo* info, | |
| 1174 Name* name) { | |
| 1175 name_buffer_.Init(tag); | |
| 1176 name_buffer_.AppendBytes(ComputeMarker(code)); | |
| 1177 name_buffer_.AppendName(name); | |
| 1178 LogRecordedBuffer(code, shared, &name_buffer_); | |
| 1179 } | |
| 1180 | |
| 1181 | |
| 1095 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1182 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1096 Code* code, | 1183 Code* code, |
| 1097 SharedFunctionInfo* shared, | 1184 SharedFunctionInfo* shared, |
| 1098 CompilationInfo* info, | 1185 CompilationInfo* info, |
| 1099 Name* name) { | 1186 Name* name) { |
| 1100 if (!is_logging_code_events()) return; | 1187 if (!is_logging_code_events()) return; |
| 1101 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1188 |
| 1102 InitNameBuffer(tag); | 1189 JIT_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1103 name_buffer_->AppendBytes(ComputeMarker(code)); | 1190 LL_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1104 AppendName(name); | 1191 CODE_ADDRESS_MAP(CodeCreateEvent(tag, code, shared, info, name)); |
| 1105 LogRecordedBuffer(code, shared); | |
| 1106 } | |
| 1107 | 1192 |
| 1108 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1193 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1109 if (code == isolate_->builtins()->builtin( | 1194 if (code == isolate_->builtins()->builtin( |
| 1110 Builtins::kLazyCompile)) | 1195 Builtins::kLazyCompile)) |
| 1111 return; | 1196 return; |
| 1112 | 1197 |
| 1113 Log::MessageBuilder msg(log_); | 1198 Log::MessageBuilder msg(log_); |
| 1114 AppendCodeCreateHeader(&msg, tag, code); | 1199 AppendCodeCreateHeader(&msg, tag, code); |
| 1115 if (name->IsString()) { | 1200 if (name->IsString()) { |
| 1116 SmartArrayPointer<char> str = | 1201 SmartArrayPointer<char> str = |
| 1117 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1202 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1118 msg.Append("\"%s\"", *str); | 1203 msg.Append("\"%s\"", *str); |
| 1119 } else { | 1204 } else { |
| 1120 msg.AppendSymbolName(Symbol::cast(name)); | 1205 msg.AppendSymbolName(Symbol::cast(name)); |
| 1121 } | 1206 } |
| 1122 msg.Append(','); | 1207 msg.Append(','); |
| 1123 msg.AppendAddress(shared->address()); | 1208 msg.AppendAddress(shared->address()); |
| 1124 msg.Append(",%s", ComputeMarker(code)); | 1209 msg.Append(",%s", ComputeMarker(code)); |
| 1125 msg.Append('\n'); | 1210 msg.Append('\n'); |
| 1126 msg.WriteToLogFile(); | 1211 msg.WriteToLogFile(); |
| 1127 } | 1212 } |
| 1128 | 1213 |
| 1129 | 1214 |
| 1130 // Although, it is possible to extract source and line from | 1215 // Although, it is possible to extract source and line from |
| 1131 // the SharedFunctionInfo object, we left it to caller | 1216 // the SharedFunctionInfo object, we left it to caller |
| 1132 // to leave logging functions free from heap allocations. | 1217 // to leave logging functions free from heap allocations. |
| 1218 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 1219 Code* code, | |
| 1220 SharedFunctionInfo* shared, | |
| 1221 CompilationInfo* info, | |
| 1222 Name* source, int line) { | |
| 1223 name_buffer_.Init(tag); | |
| 1224 name_buffer_.AppendBytes(ComputeMarker(code)); | |
| 1225 name_buffer_.AppendString(shared->DebugName()); | |
| 1226 name_buffer_.AppendByte(' '); | |
| 1227 if (source->IsString()) { | |
| 1228 name_buffer_.AppendString(String::cast(source)); | |
| 1229 } else { | |
| 1230 name_buffer_.AppendBytes("symbol(hash "); | |
| 1231 name_buffer_.AppendHex(Name::cast(source)->Hash()); | |
| 1232 name_buffer_.AppendByte(')'); | |
| 1233 } | |
| 1234 name_buffer_.AppendByte(':'); | |
| 1235 name_buffer_.AppendInt(line); | |
| 1236 LogRecordedBuffer(code, shared, &name_buffer_); | |
| 1237 } | |
| 1238 | |
| 1239 | |
| 1133 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1240 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1134 Code* code, | 1241 Code* code, |
| 1135 SharedFunctionInfo* shared, | 1242 SharedFunctionInfo* shared, |
| 1136 CompilationInfo* info, | 1243 CompilationInfo* info, |
| 1137 Name* source, int line) { | 1244 Name* source, int line) { |
| 1138 if (!is_logging_code_events()) return; | 1245 if (!is_logging_code_events()) return; |
| 1139 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1246 |
| 1140 InitNameBuffer(tag); | 1247 JIT_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1141 name_buffer_->AppendBytes(ComputeMarker(code)); | 1248 LL_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1142 name_buffer_->AppendString(shared->DebugName()); | 1249 CODE_ADDRESS_MAP(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1143 name_buffer_->AppendByte(' '); | |
| 1144 if (source->IsString()) { | |
| 1145 name_buffer_->AppendString(String::cast(source)); | |
| 1146 } else { | |
| 1147 name_buffer_->AppendBytes("symbol(hash "); | |
| 1148 name_buffer_->AppendHex(Name::cast(source)->Hash()); | |
| 1149 name_buffer_->AppendByte(')'); | |
| 1150 } | |
| 1151 name_buffer_->AppendByte(':'); | |
| 1152 name_buffer_->AppendInt(line); | |
| 1153 LogRecordedBuffer(code, shared); | |
| 1154 } | |
| 1155 | 1250 |
| 1156 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1251 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1157 Log::MessageBuilder msg(log_); | 1252 Log::MessageBuilder msg(log_); |
| 1158 AppendCodeCreateHeader(&msg, tag, code); | 1253 AppendCodeCreateHeader(&msg, tag, code); |
| 1159 SmartArrayPointer<char> name = | 1254 SmartArrayPointer<char> name = |
| 1160 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1255 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1161 msg.Append("\"%s ", *name); | 1256 msg.Append("\"%s ", *name); |
| 1162 if (source->IsString()) { | 1257 if (source->IsString()) { |
| 1163 SmartArrayPointer<char> sourcestr = | 1258 SmartArrayPointer<char> sourcestr = |
| 1164 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1259 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1165 msg.Append("%s", *sourcestr); | 1260 msg.Append("%s", *sourcestr); |
| 1166 } else { | 1261 } else { |
| 1167 msg.AppendSymbolName(Symbol::cast(source)); | 1262 msg.AppendSymbolName(Symbol::cast(source)); |
| 1168 } | 1263 } |
| 1169 msg.Append(":%d\",", line); | 1264 msg.Append(":%d\",", line); |
| 1170 msg.AppendAddress(shared->address()); | 1265 msg.AppendAddress(shared->address()); |
| 1171 msg.Append(",%s", ComputeMarker(code)); | 1266 msg.Append(",%s", ComputeMarker(code)); |
| 1172 msg.Append('\n'); | 1267 msg.Append('\n'); |
| 1173 msg.WriteToLogFile(); | 1268 msg.WriteToLogFile(); |
| 1174 } | 1269 } |
| 1175 | 1270 |
| 1176 | 1271 |
| 1177 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { | 1272 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 1273 Code* code, | |
| 1274 int args_count) { | |
| 1275 name_buffer_.Init(tag); | |
| 1276 name_buffer_.AppendInt(args_count); | |
| 1277 LogRecordedBuffer(code, NULL, &name_buffer_); | |
| 1278 } | |
| 1279 | |
| 1280 | |
| 1281 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1282 Code* code, | |
| 1283 int args_count) { | |
| 1178 if (!is_logging_code_events()) return; | 1284 if (!is_logging_code_events()) return; |
| 1179 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1285 |
| 1180 InitNameBuffer(tag); | 1286 JIT_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1181 name_buffer_->AppendInt(args_count); | 1287 LL_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1182 LogRecordedBuffer(code, NULL); | 1288 CODE_ADDRESS_MAP(CodeCreateEvent(tag, code, args_count)); |
| 1183 } | |
| 1184 | 1289 |
| 1185 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1290 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1186 Log::MessageBuilder msg(log_); | 1291 Log::MessageBuilder msg(log_); |
| 1187 AppendCodeCreateHeader(&msg, tag, code); | 1292 AppendCodeCreateHeader(&msg, tag, code); |
| 1188 msg.Append("\"args_count: %d\"", args_count); | 1293 msg.Append("\"args_count: %d\"", args_count); |
| 1189 msg.Append('\n'); | 1294 msg.Append('\n'); |
| 1190 msg.WriteToLogFile(); | 1295 msg.WriteToLogFile(); |
| 1191 } | 1296 } |
| 1192 | 1297 |
| 1193 | 1298 |
| 1194 void Logger::CodeMovingGCEvent() { | 1299 void Logger::CodeMovingGCEvent() { |
| 1195 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1300 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1196 LL_LOG(CodeMovingGCEvent()); | 1301 LL_LOG(CodeMovingGCEvent()); |
| 1197 OS::SignalCodeMovingGC(); | 1302 OS::SignalCodeMovingGC(); |
| 1198 } | 1303 } |
| 1199 | 1304 |
| 1200 | 1305 |
| 1306 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { | |
| 1307 name_buffer_.Init(Logger::REG_EXP_TAG); | |
| 1308 name_buffer_.AppendString(source); | |
| 1309 LogRecordedBuffer(code, NULL, &name_buffer_); | |
| 1310 } | |
| 1311 | |
| 1312 | |
| 1201 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1313 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 1202 if (!is_logging_code_events()) return; | 1314 if (!is_logging_code_events()) return; |
| 1203 if (FLAG_ll_prof || Serializer::enabled() || jit_logger_ != NULL) { | 1315 |
| 1204 InitNameBuffer(REG_EXP_TAG); | 1316 JIT_LOG(RegExpCodeCreateEvent(code, source)); |
| 1205 name_buffer_->AppendString(source); | 1317 LL_LOG(RegExpCodeCreateEvent(code, source)); |
| 1206 LogRecordedBuffer(code, NULL); | 1318 CODE_ADDRESS_MAP(RegExpCodeCreateEvent(code, source)); |
| 1207 } | |
| 1208 | 1319 |
| 1209 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1320 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1210 Log::MessageBuilder msg(log_); | 1321 Log::MessageBuilder msg(log_); |
| 1211 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1322 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1212 msg.Append('"'); | 1323 msg.Append('"'); |
| 1213 msg.AppendDetailed(source, false); | 1324 msg.AppendDetailed(source, false); |
| 1214 msg.Append('"'); | 1325 msg.Append('"'); |
| 1215 msg.Append('\n'); | 1326 msg.Append('\n'); |
| 1216 msg.WriteToLogFile(); | 1327 msg.WriteToLogFile(); |
| 1217 } | 1328 } |
| 1218 | 1329 |
| 1219 | 1330 |
| 1220 void Logger::CodeMoveEvent(Address from, Address to) { | 1331 void Logger::CodeMoveEvent(Address from, Address to) { |
| 1221 JIT_LOG(CodeMovedEvent(from, to)); | 1332 JIT_LOG(CodeMovedEvent(from, to)); |
| 1222 if (!log_->IsEnabled()) return; | 1333 if (!log_->IsEnabled()) return; |
| 1223 LL_LOG(CodeMoveEvent(from, to)); | 1334 LL_LOG(CodeMoveEvent(from, to)); |
| 1224 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1335 CODE_ADDRESS_MAP(CodeMoveEvent(from, to)); |
| 1225 address_to_name_map_->Move(from, to); | |
| 1226 } | |
| 1227 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1336 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| 1228 } | 1337 } |
| 1229 | 1338 |
| 1230 | 1339 |
| 1231 void Logger::CodeDeleteEvent(Address from) { | 1340 void Logger::CodeDeleteEvent(Address from) { |
| 1232 JIT_LOG(CodeRemovedEvent(from)); | 1341 JIT_LOG(CodeDeleteEvent(from)); |
| 1233 if (!log_->IsEnabled()) return; | 1342 if (!log_->IsEnabled()) return; |
| 1234 LL_LOG(CodeDeleteEvent(from)); | 1343 LL_LOG(CodeDeleteEvent(from)); |
| 1235 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1344 CODE_ADDRESS_MAP(CodeDeleteEvent(from)); |
| 1236 address_to_name_map_->Remove(from); | |
| 1237 } | |
| 1238 DeleteEventInternal(CODE_DELETE_EVENT, from); | 1345 DeleteEventInternal(CODE_DELETE_EVENT, from); |
| 1239 } | 1346 } |
| 1240 | 1347 |
| 1348 | |
| 1241 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1349 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1242 int pc_offset, | 1350 int pc_offset, |
| 1243 int position) { | 1351 int position) { |
| 1244 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1352 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1245 pc_offset, | 1353 pc_offset, |
| 1246 position, | 1354 position, |
| 1247 JitCodeEvent::POSITION)); | 1355 JitCodeEvent::POSITION)); |
| 1248 } | 1356 } |
| 1249 | 1357 |
| 1358 | |
| 1250 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, | 1359 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, |
| 1251 int pc_offset, | 1360 int pc_offset, |
| 1252 int position) { | 1361 int position) { |
| 1253 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1362 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1254 pc_offset, | 1363 pc_offset, |
| 1255 position, | 1364 position, |
| 1256 JitCodeEvent::STATEMENT_POSITION)); | 1365 JitCodeEvent::STATEMENT_POSITION)); |
| 1257 } | 1366 } |
| 1258 | 1367 |
| 1259 | 1368 |
| 1260 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { | 1369 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { |
| 1261 if (jit_logger_ != NULL) { | 1370 if (jit_logger_ != NULL) { |
| 1262 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); | 1371 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); |
| 1263 } | 1372 } |
| 1264 } | 1373 } |
| 1265 | 1374 |
| 1375 | |
| 1266 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | 1376 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, |
| 1267 void* jit_handler_data) { | 1377 void* jit_handler_data) { |
| 1268 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); | 1378 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
| 1269 } | 1379 } |
| 1270 | 1380 |
| 1271 | 1381 |
| 1272 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1382 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| 1273 if (!log_->IsEnabled()) return; | 1383 if (!log_->IsEnabled()) return; |
| 1274 LL_LOG(SnapshotPositionEvent(addr, pos)); | 1384 LL_LOG(SnapshotPositionEvent(addr, pos)); |
| 1275 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1385 if (Serializer::enabled()) { |
| 1276 const char* code_name = address_to_name_map_->Lookup(addr); | 1386 const char* code_name = code_address_map_->Lookup(addr); |
| 1277 if (code_name == NULL) return; // Not a code object. | 1387 if (code_name == NULL) return; // Not a code object. |
| 1278 Log::MessageBuilder msg(log_); | 1388 Log::MessageBuilder msg(log_); |
| 1279 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | 1389 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1280 msg.AppendDoubleQuotedString(code_name); | 1390 msg.AppendDoubleQuotedString(code_name); |
| 1281 msg.Append("\n"); | 1391 msg.Append("\n"); |
| 1282 msg.WriteToLogFile(); | 1392 msg.WriteToLogFile(); |
| 1283 } | 1393 } |
| 1284 if (!FLAG_log_snapshot_positions) return; | 1394 if (!FLAG_log_snapshot_positions) return; |
| 1285 Log::MessageBuilder msg(log_); | 1395 Log::MessageBuilder msg(log_); |
| 1286 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 1396 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1602 description = "A keyed call IC from the snapshot"; | 1712 description = "A keyed call IC from the snapshot"; |
| 1603 tag = Logger::KEYED_CALL_IC_TAG; | 1713 tag = Logger::KEYED_CALL_IC_TAG; |
| 1604 break; | 1714 break; |
| 1605 case Code::NUMBER_OF_KINDS: | 1715 case Code::NUMBER_OF_KINDS: |
| 1606 break; | 1716 break; |
| 1607 } | 1717 } |
| 1608 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); | 1718 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); |
| 1609 } | 1719 } |
| 1610 | 1720 |
| 1611 | 1721 |
| 1612 void Logger::RegisterSnapshotCodeName(Code* code, | |
| 1613 const char* name, | |
| 1614 int name_size) { | |
| 1615 ASSERT(Serializer::enabled()); | |
| 1616 if (address_to_name_map_ == NULL) { | |
| 1617 address_to_name_map_ = new NameMap; | |
| 1618 } | |
| 1619 address_to_name_map_->Insert(code->address(), name, name_size); | |
| 1620 } | |
| 1621 | |
| 1622 | |
| 1623 LowLevelLogger::LowLevelLogger(const char* name) | 1722 LowLevelLogger::LowLevelLogger(const char* name) |
| 1624 : ll_output_handle_(NULL) { | 1723 : ll_output_handle_(NULL) { |
| 1625 // Open the low-level log file. | 1724 // Open the low-level log file. |
| 1626 size_t len = strlen(name); | 1725 size_t len = strlen(name); |
| 1627 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt))); | 1726 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt))); |
| 1628 OS::MemCopy(ll_name.start(), name, len); | 1727 OS::MemCopy(ll_name.start(), name, len); |
| 1629 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt)); | 1728 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt)); |
| 1630 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); | 1729 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); |
| 1631 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize); | 1730 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize); |
| 1632 | 1731 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1648 #elif V8_TARGET_ARCH_ARM | 1747 #elif V8_TARGET_ARCH_ARM |
| 1649 const char arch[] = "arm"; | 1748 const char arch[] = "arm"; |
| 1650 #elif V8_TARGET_ARCH_MIPS | 1749 #elif V8_TARGET_ARCH_MIPS |
| 1651 const char arch[] = "mips"; | 1750 const char arch[] = "mips"; |
| 1652 #else | 1751 #else |
| 1653 const char arch[] = "unknown"; | 1752 const char arch[] = "unknown"; |
| 1654 #endif | 1753 #endif |
| 1655 LogWriteBytes(arch, sizeof(arch)); | 1754 LogWriteBytes(arch, sizeof(arch)); |
| 1656 } | 1755 } |
| 1657 | 1756 |
| 1658 void LowLevelLogger::CodeCreateEvent(Code* code, | 1757 |
| 1659 const char* name, | 1758 void LowLevelLogger::LogRecordedBuffer(Code* code, |
| 1660 int name_size) { | 1759 SharedFunctionInfo*, |
| 1760 NameBuffer* name_buffer) { | |
| 1661 CodeCreateStruct event; | 1761 CodeCreateStruct event; |
| 1662 event.name_size = name_size; | 1762 event.name_size = name_buffer->size(); |
| 1663 event.code_address = code->instruction_start(); | 1763 event.code_address = code->instruction_start(); |
| 1664 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | 1764 ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
| 1665 event.code_size = code->instruction_size(); | 1765 event.code_size = code->instruction_size(); |
| 1666 LogWriteStruct(event); | 1766 LogWriteStruct(event); |
| 1667 LogWriteBytes(name, name_size); | 1767 LogWriteBytes(name_buffer->get(), name_buffer->size()); |
| 1668 LogWriteBytes( | 1768 LogWriteBytes( |
| 1669 reinterpret_cast<const char*>(code->instruction_start()), | 1769 reinterpret_cast<const char*>(code->instruction_start()), |
| 1670 code->instruction_size()); | 1770 code->instruction_size()); |
| 1671 } | 1771 } |
| 1672 | 1772 |
| 1673 | 1773 |
| 1674 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | 1774 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { |
| 1675 CodeMoveStruct event; | 1775 CodeMoveStruct event; |
| 1676 event.from_address = from + Code::kHeaderSize; | 1776 event.from_address = from + Code::kHeaderSize; |
| 1677 event.to_address = to + Code::kHeaderSize; | 1777 event.to_address = to + Code::kHeaderSize; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1960 | 2060 |
| 1961 if (jit_logger_) { | 2061 if (jit_logger_) { |
| 1962 delete jit_logger_; | 2062 delete jit_logger_; |
| 1963 jit_logger_ = NULL; | 2063 jit_logger_ = NULL; |
| 1964 } | 2064 } |
| 1965 | 2065 |
| 1966 return log_->Close(); | 2066 return log_->Close(); |
| 1967 } | 2067 } |
| 1968 | 2068 |
| 1969 } } // namespace v8::internal | 2069 } } // namespace v8::internal |
| OLD | NEW |