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