| 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 17 matching lines...) Expand all Loading... |
| 28 #include <stdarg.h> | 28 #include <stdarg.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "code-stubs.h" | 33 #include "code-stubs.h" |
| 34 #include "cpu-profiler.h" | 34 #include "cpu-profiler.h" |
| 35 #include "deoptimizer.h" | 35 #include "deoptimizer.h" |
| 36 #include "global-handles.h" | 36 #include "global-handles.h" |
| 37 #include "log.h" | 37 #include "log.h" |
| 38 #include "log-utils.h" |
| 38 #include "macro-assembler.h" | 39 #include "macro-assembler.h" |
| 39 #include "platform.h" | 40 #include "platform.h" |
| 40 #include "runtime-profiler.h" | 41 #include "runtime-profiler.h" |
| 41 #include "serialize.h" | 42 #include "serialize.h" |
| 42 #include "string-stream.h" | 43 #include "string-stream.h" |
| 43 #include "vm-state-inl.h" | 44 #include "vm-state-inl.h" |
| 44 | 45 |
| 45 namespace v8 { | 46 namespace v8 { |
| 46 namespace internal { | 47 namespace internal { |
| 47 | 48 |
| 48 | 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 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 58 static const char* ComputeMarker(Code* code) { |
| 59 switch (code->kind()) { |
| 60 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 61 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 62 default: return ""; |
| 63 } |
| 64 } |
| 65 |
| 66 |
| 67 class CodeEventLogger { |
| 68 public: |
| 69 virtual ~CodeEventLogger() { } |
| 70 |
| 71 void CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 72 Code* code, |
| 73 const char* comment); |
| 74 void CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 75 Code* code, |
| 76 Name* name); |
| 77 void CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 78 Code* code, |
| 79 int args_count); |
| 80 void CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 81 Code* code, |
| 82 SharedFunctionInfo* shared, |
| 83 CompilationInfo* info, |
| 84 Name* name); |
| 85 void CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 86 Code* code, |
| 87 SharedFunctionInfo* shared, |
| 88 CompilationInfo* info, |
| 89 Name* source, |
| 90 int line); |
| 91 void RegExpCodeCreateEvent(Code* code, String* source); |
| 92 |
| 93 protected: |
| 94 class NameBuffer { |
| 95 public: |
| 96 NameBuffer() { Reset(); } |
| 97 |
| 98 void Reset() { |
| 99 utf8_pos_ = 0; |
| 100 } |
| 101 |
| 102 void Init(Logger::LogEventsAndTags tag) { |
| 103 Reset(); |
| 104 AppendBytes(kLogEventsNames[tag]); |
| 105 AppendByte(':'); |
| 106 } |
| 107 |
| 108 void AppendName(Name* name) { |
| 109 if (name->IsString()) { |
| 110 AppendString(String::cast(name)); |
| 111 } else { |
| 112 Symbol* symbol = Symbol::cast(name); |
| 113 AppendBytes("symbol("); |
| 114 if (!symbol->name()->IsUndefined()) { |
| 115 AppendBytes("\""); |
| 116 AppendString(String::cast(symbol->name())); |
| 117 AppendBytes("\" "); |
| 118 } |
| 119 AppendBytes("hash "); |
| 120 AppendHex(symbol->Hash()); |
| 121 AppendByte(')'); |
| 122 } |
| 123 } |
| 124 |
| 125 void AppendString(String* str) { |
| 126 if (str == NULL) return; |
| 127 int uc16_length = Min(str->length(), kUtf16BufferSize); |
| 128 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); |
| 129 int previous = unibrow::Utf16::kNoPreviousCharacter; |
| 130 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { |
| 131 uc16 c = utf16_buffer[i]; |
| 132 if (c <= unibrow::Utf8::kMaxOneByteChar) { |
| 133 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); |
| 134 } else { |
| 135 int char_length = unibrow::Utf8::Length(c, previous); |
| 136 if (utf8_pos_ + char_length > kUtf8BufferSize) break; |
| 137 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); |
| 138 utf8_pos_ += char_length; |
| 139 } |
| 140 previous = c; |
| 141 } |
| 142 } |
| 143 |
| 144 void AppendBytes(const char* bytes, int size) { |
| 145 size = Min(size, kUtf8BufferSize - utf8_pos_); |
| 146 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); |
| 147 utf8_pos_ += size; |
| 148 } |
| 149 |
| 150 void AppendBytes(const char* bytes) { |
| 151 AppendBytes(bytes, StrLength(bytes)); |
| 152 } |
| 153 |
| 154 void AppendByte(char c) { |
| 155 if (utf8_pos_ >= kUtf8BufferSize) return; |
| 156 utf8_buffer_[utf8_pos_++] = c; |
| 157 } |
| 158 |
| 159 void AppendInt(int n) { |
| 160 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 161 kUtf8BufferSize - utf8_pos_); |
| 162 int size = OS::SNPrintF(buffer, "%d", n); |
| 163 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| 164 utf8_pos_ += size; |
| 165 } |
| 166 } |
| 167 |
| 168 void AppendHex(uint32_t n) { |
| 169 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 170 kUtf8BufferSize - utf8_pos_); |
| 171 int size = OS::SNPrintF(buffer, "%x", n); |
| 172 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| 173 utf8_pos_ += size; |
| 174 } |
| 175 } |
| 176 |
| 177 const char* get() { return utf8_buffer_; } |
| 178 int size() const { return utf8_pos_; } |
| 179 |
| 180 private: |
| 181 static const int kUtf8BufferSize = 512; |
| 182 static const int kUtf16BufferSize = 128; |
| 183 |
| 184 int utf8_pos_; |
| 185 char utf8_buffer_[kUtf8BufferSize]; |
| 186 uc16 utf16_buffer[kUtf16BufferSize]; |
| 187 }; |
| 188 |
| 189 private: |
| 190 virtual void LogRecordedBuffer(Code* code, |
| 191 SharedFunctionInfo* shared, |
| 192 NameBuffer* name_buffer) = 0; |
| 193 |
| 194 NameBuffer name_buffer_; |
| 195 }; |
| 196 |
| 197 |
| 198 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 199 Code* code, |
| 200 const char* comment) { |
| 201 name_buffer_.Init(tag); |
| 202 name_buffer_.AppendBytes(comment); |
| 203 LogRecordedBuffer(code, NULL, &name_buffer_); |
| 204 } |
| 205 |
| 206 |
| 207 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 208 Code* code, |
| 209 Name* name) { |
| 210 name_buffer_.Init(tag); |
| 211 name_buffer_.AppendName(name); |
| 212 LogRecordedBuffer(code, NULL, &name_buffer_); |
| 213 } |
| 214 |
| 215 |
| 216 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 217 Code* code, |
| 218 SharedFunctionInfo* shared, |
| 219 CompilationInfo* info, |
| 220 Name* name) { |
| 221 name_buffer_.Init(tag); |
| 222 name_buffer_.AppendBytes(ComputeMarker(code)); |
| 223 name_buffer_.AppendName(name); |
| 224 LogRecordedBuffer(code, shared, &name_buffer_); |
| 225 } |
| 226 |
| 227 |
| 228 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 229 Code* code, |
| 230 SharedFunctionInfo* shared, |
| 231 CompilationInfo* info, |
| 232 Name* source, int line) { |
| 233 name_buffer_.Init(tag); |
| 234 name_buffer_.AppendBytes(ComputeMarker(code)); |
| 235 name_buffer_.AppendString(shared->DebugName()); |
| 236 name_buffer_.AppendByte(' '); |
| 237 if (source->IsString()) { |
| 238 name_buffer_.AppendString(String::cast(source)); |
| 239 } else { |
| 240 name_buffer_.AppendBytes("symbol(hash "); |
| 241 name_buffer_.AppendHex(Name::cast(source)->Hash()); |
| 242 name_buffer_.AppendByte(')'); |
| 243 } |
| 244 name_buffer_.AppendByte(':'); |
| 245 name_buffer_.AppendInt(line); |
| 246 LogRecordedBuffer(code, shared, &name_buffer_); |
| 247 } |
| 248 |
| 249 |
| 250 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 251 Code* code, |
| 252 int args_count) { |
| 253 name_buffer_.Init(tag); |
| 254 name_buffer_.AppendInt(args_count); |
| 255 LogRecordedBuffer(code, NULL, &name_buffer_); |
| 256 } |
| 257 |
| 258 |
| 259 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 260 name_buffer_.Init(Logger::REG_EXP_TAG); |
| 261 name_buffer_.AppendString(source); |
| 262 LogRecordedBuffer(code, NULL, &name_buffer_); |
| 263 } |
| 264 |
| 265 |
| 49 // Low-level logging support. | 266 // Low-level logging support. |
| 50 class LowLevelLogger { | 267 class LowLevelLogger : public CodeEventLogger { |
| 51 public: | 268 public: |
| 52 explicit LowLevelLogger(const char* file_name); | 269 explicit LowLevelLogger(const char* file_name); |
| 53 ~LowLevelLogger(); | 270 virtual ~LowLevelLogger(); |
| 54 | 271 |
| 55 void CodeCreateEvent(Code* code, const char* name, int name_size); | |
| 56 void CodeMoveEvent(Address from, Address to); | 272 void CodeMoveEvent(Address from, Address to); |
| 57 void CodeDeleteEvent(Address from); | 273 void CodeDeleteEvent(Address from); |
| 58 void SnapshotPositionEvent(Address addr, int pos); | 274 void SnapshotPositionEvent(Address addr, int pos); |
| 59 void CodeMovingGCEvent(); | 275 void CodeMovingGCEvent(); |
| 60 | 276 |
| 61 private: | 277 private: |
| 278 virtual void LogRecordedBuffer(Code* code, |
| 279 SharedFunctionInfo* shared, |
| 280 NameBuffer* name_buffer); |
| 281 |
| 62 // Low-level profiling event structures. | 282 // Low-level profiling event structures. |
| 63 | |
| 64 struct CodeCreateStruct { | 283 struct CodeCreateStruct { |
| 65 static const char kTag = 'C'; | 284 static const char kTag = 'C'; |
| 66 | 285 |
| 67 int32_t name_size; | 286 int32_t name_size; |
| 68 Address code_address; | 287 Address code_address; |
| 69 int32_t code_size; | 288 int32_t code_size; |
| 70 }; | 289 }; |
| 71 | 290 |
| 72 | 291 |
| 73 struct CodeMoveStruct { | 292 struct CodeMoveStruct { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 char tag = T::kTag; | 330 char tag = T::kTag; |
| 112 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag)); | 331 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag)); |
| 113 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s)); | 332 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s)); |
| 114 } | 333 } |
| 115 | 334 |
| 116 FILE* ll_output_handle_; | 335 FILE* ll_output_handle_; |
| 117 }; | 336 }; |
| 118 | 337 |
| 119 const char LowLevelLogger::kLogExt[] = ".ll"; | 338 const char LowLevelLogger::kLogExt[] = ".ll"; |
| 120 | 339 |
| 340 LowLevelLogger::LowLevelLogger(const char* name) |
| 341 : ll_output_handle_(NULL) { |
| 342 // Open the low-level log file. |
| 343 size_t len = strlen(name); |
| 344 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt))); |
| 345 OS::MemCopy(ll_name.start(), name, len); |
| 346 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt)); |
| 347 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); |
| 348 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize); |
| 349 |
| 350 LogCodeInfo(); |
| 351 } |
| 352 |
| 353 |
| 354 LowLevelLogger::~LowLevelLogger() { |
| 355 fclose(ll_output_handle_); |
| 356 ll_output_handle_ = NULL; |
| 357 } |
| 358 |
| 359 |
| 360 void LowLevelLogger::LogCodeInfo() { |
| 361 #if V8_TARGET_ARCH_IA32 |
| 362 const char arch[] = "ia32"; |
| 363 #elif V8_TARGET_ARCH_X64 |
| 364 const char arch[] = "x64"; |
| 365 #elif V8_TARGET_ARCH_ARM |
| 366 const char arch[] = "arm"; |
| 367 #elif V8_TARGET_ARCH_MIPS |
| 368 const char arch[] = "mips"; |
| 369 #else |
| 370 const char arch[] = "unknown"; |
| 371 #endif |
| 372 LogWriteBytes(arch, sizeof(arch)); |
| 373 } |
| 374 |
| 375 |
| 376 void LowLevelLogger::LogRecordedBuffer(Code* code, |
| 377 SharedFunctionInfo*, |
| 378 NameBuffer* name_buffer) { |
| 379 CodeCreateStruct event; |
| 380 event.name_size = name_buffer->size(); |
| 381 event.code_address = code->instruction_start(); |
| 382 ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
| 383 event.code_size = code->instruction_size(); |
| 384 LogWriteStruct(event); |
| 385 LogWriteBytes(name_buffer->get(), name_buffer->size()); |
| 386 LogWriteBytes( |
| 387 reinterpret_cast<const char*>(code->instruction_start()), |
| 388 code->instruction_size()); |
| 389 } |
| 390 |
| 391 |
| 392 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { |
| 393 CodeMoveStruct event; |
| 394 event.from_address = from + Code::kHeaderSize; |
| 395 event.to_address = to + Code::kHeaderSize; |
| 396 LogWriteStruct(event); |
| 397 } |
| 398 |
| 399 |
| 400 void LowLevelLogger::CodeDeleteEvent(Address from) { |
| 401 CodeDeleteStruct event; |
| 402 event.address = from + Code::kHeaderSize; |
| 403 LogWriteStruct(event); |
| 404 } |
| 405 |
| 406 |
| 407 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { |
| 408 SnapshotPositionStruct event; |
| 409 event.address = addr + Code::kHeaderSize; |
| 410 event.position = pos; |
| 411 LogWriteStruct(event); |
| 412 } |
| 413 |
| 414 |
| 415 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { |
| 416 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); |
| 417 ASSERT(static_cast<size_t>(size) == rv); |
| 418 USE(rv); |
| 419 } |
| 420 |
| 421 |
| 422 void LowLevelLogger::CodeMovingGCEvent() { |
| 423 const char tag = kCodeMovingGCTag; |
| 424 |
| 425 LogWriteBytes(&tag, sizeof(tag)); |
| 426 } |
| 427 |
| 428 |
| 121 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 429 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 122 | 430 |
| 123 | 431 |
| 432 class CodeAddressMap: public CodeEventLogger { |
| 433 public: |
| 434 CodeAddressMap() { } |
| 435 virtual ~CodeAddressMap() { } |
| 436 |
| 437 void CodeMoveEvent(Address from, Address to) { |
| 438 address_to_name_map_.Move(from, to); |
| 439 } |
| 440 |
| 441 void CodeDeleteEvent(Address from) { |
| 442 address_to_name_map_.Remove(from); |
| 443 } |
| 444 |
| 445 const char* Lookup(Address address) { |
| 446 return address_to_name_map_.Lookup(address); |
| 447 } |
| 448 |
| 449 private: |
| 450 class NameMap { |
| 451 public: |
| 452 NameMap() : impl_(&PointerEquals) {} |
| 453 |
| 454 ~NameMap() { |
| 455 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { |
| 456 DeleteArray(static_cast<const char*>(p->value)); |
| 457 } |
| 458 } |
| 459 |
| 460 void Insert(Address code_address, const char* name, int name_size) { |
| 461 HashMap::Entry* entry = FindOrCreateEntry(code_address); |
| 462 if (entry->value == NULL) { |
| 463 entry->value = CopyName(name, name_size); |
| 464 } |
| 465 } |
| 466 |
| 467 const char* Lookup(Address code_address) { |
| 468 HashMap::Entry* entry = FindEntry(code_address); |
| 469 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; |
| 470 } |
| 471 |
| 472 void Remove(Address code_address) { |
| 473 HashMap::Entry* entry = FindEntry(code_address); |
| 474 if (entry != NULL) { |
| 475 DeleteArray(static_cast<char*>(entry->value)); |
| 476 RemoveEntry(entry); |
| 477 } |
| 478 } |
| 479 |
| 480 void Move(Address from, Address to) { |
| 481 if (from == to) return; |
| 482 HashMap::Entry* from_entry = FindEntry(from); |
| 483 ASSERT(from_entry != NULL); |
| 484 void* value = from_entry->value; |
| 485 RemoveEntry(from_entry); |
| 486 HashMap::Entry* to_entry = FindOrCreateEntry(to); |
| 487 ASSERT(to_entry->value == NULL); |
| 488 to_entry->value = value; |
| 489 } |
| 490 |
| 491 private: |
| 492 static bool PointerEquals(void* lhs, void* rhs) { |
| 493 return lhs == rhs; |
| 494 } |
| 495 |
| 496 static char* CopyName(const char* name, int name_size) { |
| 497 char* result = NewArray<char>(name_size + 1); |
| 498 for (int i = 0; i < name_size; ++i) { |
| 499 char c = name[i]; |
| 500 if (c == '\0') c = ' '; |
| 501 result[i] = c; |
| 502 } |
| 503 result[name_size] = '\0'; |
| 504 return result; |
| 505 } |
| 506 |
| 507 HashMap::Entry* FindOrCreateEntry(Address code_address) { |
| 508 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); |
| 509 } |
| 510 |
| 511 HashMap::Entry* FindEntry(Address code_address) { |
| 512 return impl_.Lookup(code_address, |
| 513 ComputePointerHash(code_address), |
| 514 false); |
| 515 } |
| 516 |
| 517 void RemoveEntry(HashMap::Entry* entry) { |
| 518 impl_.Remove(entry->key, entry->hash); |
| 519 } |
| 520 |
| 521 HashMap impl_; |
| 522 |
| 523 DISALLOW_COPY_AND_ASSIGN(NameMap); |
| 524 }; |
| 525 |
| 526 virtual void LogRecordedBuffer(Code* code, |
| 527 SharedFunctionInfo*, |
| 528 NameBuffer* name_buffer) { |
| 529 address_to_name_map_.Insert(code->address(), |
| 530 name_buffer->get(), |
| 531 name_buffer->size()); |
| 532 } |
| 533 |
| 534 NameMap address_to_name_map_; |
| 535 }; |
| 536 |
| 537 |
| 538 #define CODE_ADDRESS_MAP_LOG(Call)\ |
| 539 if (Serializer::enabled()) code_address_map_->Call; |
| 540 |
| 541 |
| 542 class JitLogger : public CodeEventLogger { |
| 543 public: |
| 544 explicit JitLogger(JitCodeEventHandler code_event_handler); |
| 545 |
| 546 void CodeMovedEvent(Address from, Address to); |
| 547 void CodeDeleteEvent(Address from); |
| 548 void AddCodeLinePosInfoEvent( |
| 549 void* jit_handler_data, |
| 550 int pc_offset, |
| 551 int position, |
| 552 JitCodeEvent::PositionType position_type); |
| 553 void* StartCodePosInfoEvent(); |
| 554 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); |
| 555 |
| 556 private: |
| 557 virtual void LogRecordedBuffer(Code* code, |
| 558 SharedFunctionInfo* shared, |
| 559 CodeEventLogger::NameBuffer* name_buffer); |
| 560 |
| 561 JitCodeEventHandler code_event_handler_; |
| 562 }; |
| 563 |
| 564 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
| 565 |
| 566 |
| 567 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
| 568 : code_event_handler_(code_event_handler) { |
| 569 } |
| 570 |
| 571 |
| 572 void JitLogger::LogRecordedBuffer(Code* code, |
| 573 SharedFunctionInfo* shared, |
| 574 CodeEventLogger::NameBuffer* name_buffer) { |
| 575 JitCodeEvent event; |
| 576 memset(&event, 0, sizeof(event)); |
| 577 event.type = JitCodeEvent::CODE_ADDED; |
| 578 event.code_start = code->instruction_start(); |
| 579 event.code_len = code->instruction_size(); |
| 580 Handle<Script> script_handle; |
| 581 if (shared && shared->script()->IsScript()) { |
| 582 script_handle = Handle<Script>(Script::cast(shared->script())); |
| 583 } |
| 584 event.script = ToApiHandle<v8::Script>(script_handle); |
| 585 event.name.str = name_buffer->get(); |
| 586 event.name.len = name_buffer->size(); |
| 587 code_event_handler_(&event); |
| 588 } |
| 589 |
| 590 |
| 591 void JitLogger::CodeMovedEvent(Address from, Address to) { |
| 592 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
| 593 |
| 594 JitCodeEvent event; |
| 595 event.type = JitCodeEvent::CODE_MOVED; |
| 596 event.code_start = from_code->instruction_start(); |
| 597 event.code_len = from_code->instruction_size(); |
| 598 |
| 599 // Calculate the header size. |
| 600 const size_t header_size = |
| 601 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); |
| 602 |
| 603 // Calculate the new start address of the instructions. |
| 604 event.new_code_start = |
| 605 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; |
| 606 |
| 607 code_event_handler_(&event); |
| 608 } |
| 609 |
| 610 |
| 611 void JitLogger::CodeDeleteEvent(Address from) { |
| 612 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
| 613 |
| 614 JitCodeEvent event; |
| 615 event.type = JitCodeEvent::CODE_REMOVED; |
| 616 event.code_start = from_code->instruction_start(); |
| 617 event.code_len = from_code->instruction_size(); |
| 618 |
| 619 code_event_handler_(&event); |
| 620 } |
| 621 |
| 622 void JitLogger::AddCodeLinePosInfoEvent( |
| 623 void* jit_handler_data, |
| 624 int pc_offset, |
| 625 int position, |
| 626 JitCodeEvent::PositionType position_type) { |
| 627 JitCodeEvent event; |
| 628 memset(&event, 0, sizeof(event)); |
| 629 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO; |
| 630 event.user_data = jit_handler_data; |
| 631 event.line_info.offset = pc_offset; |
| 632 event.line_info.pos = position; |
| 633 event.line_info.position_type = position_type; |
| 634 |
| 635 code_event_handler_(&event); |
| 636 } |
| 637 |
| 638 |
| 639 void* JitLogger::StartCodePosInfoEvent() { |
| 640 JitCodeEvent event; |
| 641 memset(&event, 0, sizeof(event)); |
| 642 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; |
| 643 |
| 644 code_event_handler_(&event); |
| 645 return event.user_data; |
| 646 } |
| 647 |
| 648 |
| 649 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) { |
| 650 JitCodeEvent event; |
| 651 memset(&event, 0, sizeof(event)); |
| 652 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; |
| 653 event.code_start = code->instruction_start(); |
| 654 event.user_data = jit_handler_data; |
| 655 |
| 656 code_event_handler_(&event); |
| 657 } |
| 658 |
| 659 |
| 124 // The Profiler samples pc and sp values for the main thread. | 660 // The Profiler samples pc and sp values for the main thread. |
| 125 // Each sample is appended to a circular buffer. | 661 // Each sample is appended to a circular buffer. |
| 126 // An independent thread removes data and writes it to the log. | 662 // An independent thread removes data and writes it to the log. |
| 127 // This design minimizes the time spent in the sampler. | 663 // This design minimizes the time spent in the sampler. |
| 128 // | 664 // |
| 129 class Profiler: public Thread { | 665 class Profiler: public Thread { |
| 130 public: | 666 public: |
| 131 explicit Profiler(Isolate* isolate); | 667 explicit Profiler(Isolate* isolate); |
| 132 void Engage(); | 668 void Engage(); |
| 133 void Disengage(); | 669 void Disengage(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 LOG(isolate_, TickEvent(&sample, overflow)); | 819 LOG(isolate_, TickEvent(&sample, overflow)); |
| 284 overflow = Remove(&sample); | 820 overflow = Remove(&sample); |
| 285 } | 821 } |
| 286 } | 822 } |
| 287 | 823 |
| 288 | 824 |
| 289 // | 825 // |
| 290 // Logger class implementation. | 826 // Logger class implementation. |
| 291 // | 827 // |
| 292 | 828 |
| 293 class Logger::NameMap { | |
| 294 public: | |
| 295 NameMap() : impl_(&PointerEquals) {} | |
| 296 | |
| 297 ~NameMap() { | |
| 298 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | |
| 299 DeleteArray(static_cast<const char*>(p->value)); | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 void Insert(Address code_address, const char* name, int name_size) { | |
| 304 HashMap::Entry* entry = FindOrCreateEntry(code_address); | |
| 305 if (entry->value == NULL) { | |
| 306 entry->value = CopyName(name, name_size); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 const char* Lookup(Address code_address) { | |
| 311 HashMap::Entry* entry = FindEntry(code_address); | |
| 312 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; | |
| 313 } | |
| 314 | |
| 315 void Remove(Address code_address) { | |
| 316 HashMap::Entry* entry = FindEntry(code_address); | |
| 317 if (entry != NULL) { | |
| 318 DeleteArray(static_cast<char*>(entry->value)); | |
| 319 RemoveEntry(entry); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 void Move(Address from, Address to) { | |
| 324 if (from == to) return; | |
| 325 HashMap::Entry* from_entry = FindEntry(from); | |
| 326 ASSERT(from_entry != NULL); | |
| 327 void* value = from_entry->value; | |
| 328 RemoveEntry(from_entry); | |
| 329 HashMap::Entry* to_entry = FindOrCreateEntry(to); | |
| 330 ASSERT(to_entry->value == NULL); | |
| 331 to_entry->value = value; | |
| 332 } | |
| 333 | |
| 334 private: | |
| 335 static bool PointerEquals(void* lhs, void* rhs) { | |
| 336 return lhs == rhs; | |
| 337 } | |
| 338 | |
| 339 static char* CopyName(const char* name, int name_size) { | |
| 340 char* result = NewArray<char>(name_size + 1); | |
| 341 for (int i = 0; i < name_size; ++i) { | |
| 342 char c = name[i]; | |
| 343 if (c == '\0') c = ' '; | |
| 344 result[i] = c; | |
| 345 } | |
| 346 result[name_size] = '\0'; | |
| 347 return result; | |
| 348 } | |
| 349 | |
| 350 HashMap::Entry* FindOrCreateEntry(Address code_address) { | |
| 351 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); | |
| 352 } | |
| 353 | |
| 354 HashMap::Entry* FindEntry(Address code_address) { | |
| 355 return impl_.Lookup(code_address, ComputePointerHash(code_address), false); | |
| 356 } | |
| 357 | |
| 358 void RemoveEntry(HashMap::Entry* entry) { | |
| 359 impl_.Remove(entry->key, entry->hash); | |
| 360 } | |
| 361 | |
| 362 HashMap impl_; | |
| 363 | |
| 364 DISALLOW_COPY_AND_ASSIGN(NameMap); | |
| 365 }; | |
| 366 | |
| 367 | |
| 368 class Logger::NameBuffer { | |
| 369 public: | |
| 370 NameBuffer() { Reset(); } | |
| 371 | |
| 372 void Reset() { | |
| 373 utf8_pos_ = 0; | |
| 374 } | |
| 375 | |
| 376 void AppendString(String* str) { | |
| 377 if (str == NULL) return; | |
| 378 int uc16_length = Min(str->length(), kUtf16BufferSize); | |
| 379 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); | |
| 380 int previous = unibrow::Utf16::kNoPreviousCharacter; | |
| 381 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
| 382 uc16 c = utf16_buffer[i]; | |
| 383 if (c <= unibrow::Utf8::kMaxOneByteChar) { | |
| 384 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); | |
| 385 } else { | |
| 386 int char_length = unibrow::Utf8::Length(c, previous); | |
| 387 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
| 388 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); | |
| 389 utf8_pos_ += char_length; | |
| 390 } | |
| 391 previous = c; | |
| 392 } | |
| 393 } | |
| 394 | |
| 395 void AppendBytes(const char* bytes, int size) { | |
| 396 size = Min(size, kUtf8BufferSize - utf8_pos_); | |
| 397 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); | |
| 398 utf8_pos_ += size; | |
| 399 } | |
| 400 | |
| 401 void AppendBytes(const char* bytes) { | |
| 402 AppendBytes(bytes, StrLength(bytes)); | |
| 403 } | |
| 404 | |
| 405 void AppendByte(char c) { | |
| 406 if (utf8_pos_ >= kUtf8BufferSize) return; | |
| 407 utf8_buffer_[utf8_pos_++] = c; | |
| 408 } | |
| 409 | |
| 410 void AppendInt(int n) { | |
| 411 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); | |
| 412 int size = OS::SNPrintF(buffer, "%d", n); | |
| 413 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 414 utf8_pos_ += size; | |
| 415 } | |
| 416 } | |
| 417 | |
| 418 void AppendHex(uint32_t n) { | |
| 419 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); | |
| 420 int size = OS::SNPrintF(buffer, "%x", n); | |
| 421 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 422 utf8_pos_ += size; | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 const char* get() { return utf8_buffer_; } | |
| 427 int size() const { return utf8_pos_; } | |
| 428 | |
| 429 private: | |
| 430 static const int kUtf8BufferSize = 512; | |
| 431 static const int kUtf16BufferSize = 128; | |
| 432 | |
| 433 int utf8_pos_; | |
| 434 char utf8_buffer_[kUtf8BufferSize]; | |
| 435 uc16 utf16_buffer[kUtf16BufferSize]; | |
| 436 }; | |
| 437 | |
| 438 | |
| 439 Logger::Logger(Isolate* isolate) | 829 Logger::Logger(Isolate* isolate) |
| 440 : isolate_(isolate), | 830 : isolate_(isolate), |
| 441 ticker_(NULL), | 831 ticker_(NULL), |
| 442 profiler_(NULL), | 832 profiler_(NULL), |
| 443 log_events_(NULL), | 833 log_events_(NULL), |
| 444 logging_nesting_(0), | 834 logging_nesting_(0), |
| 445 cpu_profiler_nesting_(0), | 835 cpu_profiler_nesting_(0), |
| 446 log_(new Log(this)), | 836 log_(new Log(this)), |
| 447 ll_logger_(NULL), | 837 ll_logger_(NULL), |
| 448 name_buffer_(new NameBuffer), | 838 jit_logger_(NULL), |
| 449 address_to_name_map_(NULL), | 839 code_address_map_(new CodeAddressMap), |
| 450 is_initialized_(false), | 840 is_initialized_(false), |
| 451 code_event_handler_(NULL), | |
| 452 last_address_(NULL), | 841 last_address_(NULL), |
| 453 prev_sp_(NULL), | 842 prev_sp_(NULL), |
| 454 prev_function_(NULL), | 843 prev_function_(NULL), |
| 455 prev_to_(NULL), | 844 prev_to_(NULL), |
| 456 prev_code_(NULL), | 845 prev_code_(NULL), |
| 457 epoch_(0) { | 846 epoch_(0) { |
| 458 } | 847 } |
| 459 | 848 |
| 460 | 849 |
| 461 Logger::~Logger() { | 850 Logger::~Logger() { |
| 462 delete address_to_name_map_; | 851 delete code_address_map_; |
| 463 delete name_buffer_; | |
| 464 delete log_; | 852 delete log_; |
| 465 } | 853 } |
| 466 | 854 |
| 467 | 855 |
| 468 void Logger::IssueCodeAddedEvent(Code* code, | |
| 469 Script* script, | |
| 470 const char* name, | |
| 471 size_t name_len) { | |
| 472 JitCodeEvent event; | |
| 473 memset(&event, 0, sizeof(event)); | |
| 474 event.type = JitCodeEvent::CODE_ADDED; | |
| 475 event.code_start = code->instruction_start(); | |
| 476 event.code_len = code->instruction_size(); | |
| 477 Handle<Script> script_handle = | |
| 478 script != NULL ? Handle<Script>(script) : Handle<Script>(); | |
| 479 event.script = ToApiHandle<v8::Script>(script_handle); | |
| 480 event.name.str = name; | |
| 481 event.name.len = name_len; | |
| 482 | |
| 483 code_event_handler_(&event); | |
| 484 } | |
| 485 | |
| 486 | |
| 487 void Logger::IssueCodeMovedEvent(Address from, Address to) { | |
| 488 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 489 | |
| 490 JitCodeEvent event; | |
| 491 event.type = JitCodeEvent::CODE_MOVED; | |
| 492 event.code_start = from_code->instruction_start(); | |
| 493 event.code_len = from_code->instruction_size(); | |
| 494 | |
| 495 // Calculate the header size. | |
| 496 const size_t header_size = | |
| 497 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | |
| 498 | |
| 499 // Calculate the new start address of the instructions. | |
| 500 event.new_code_start = | |
| 501 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; | |
| 502 | |
| 503 code_event_handler_(&event); | |
| 504 } | |
| 505 | |
| 506 | |
| 507 void Logger::IssueCodeRemovedEvent(Address from) { | |
| 508 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 509 | |
| 510 JitCodeEvent event; | |
| 511 event.type = JitCodeEvent::CODE_REMOVED; | |
| 512 event.code_start = from_code->instruction_start(); | |
| 513 event.code_len = from_code->instruction_size(); | |
| 514 | |
| 515 code_event_handler_(&event); | |
| 516 } | |
| 517 | |
| 518 void Logger::IssueAddCodeLinePosInfoEvent( | |
| 519 void* jit_handler_data, | |
| 520 int pc_offset, | |
| 521 int position, | |
| 522 JitCodeEvent::PositionType position_type) { | |
| 523 JitCodeEvent event; | |
| 524 memset(&event, 0, sizeof(event)); | |
| 525 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO; | |
| 526 event.user_data = jit_handler_data; | |
| 527 event.line_info.offset = pc_offset; | |
| 528 event.line_info.pos = position; | |
| 529 event.line_info.position_type = position_type; | |
| 530 | |
| 531 code_event_handler_(&event); | |
| 532 } | |
| 533 | |
| 534 | |
| 535 void* Logger::IssueStartCodePosInfoEvent() { | |
| 536 JitCodeEvent event; | |
| 537 memset(&event, 0, sizeof(event)); | |
| 538 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; | |
| 539 | |
| 540 code_event_handler_(&event); | |
| 541 return event.user_data; | |
| 542 } | |
| 543 | |
| 544 | |
| 545 void Logger::IssueEndCodePosInfoEvent(Code* code, void* jit_handler_data) { | |
| 546 JitCodeEvent event; | |
| 547 memset(&event, 0, sizeof(event)); | |
| 548 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; | |
| 549 event.code_start = code->instruction_start(); | |
| 550 event.user_data = jit_handler_data; | |
| 551 | |
| 552 code_event_handler_(&event); | |
| 553 } | |
| 554 | |
| 555 #define DECLARE_EVENT(ignore1, name) name, | |
| 556 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | |
| 557 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | |
| 558 }; | |
| 559 #undef DECLARE_EVENT | |
| 560 | |
| 561 | |
| 562 void Logger::ProfilerBeginEvent() { | 856 void Logger::ProfilerBeginEvent() { |
| 563 if (!log_->IsEnabled()) return; | 857 if (!log_->IsEnabled()) return; |
| 564 LogMessageBuilder msg(this); | 858 Log::MessageBuilder msg(log_); |
| 565 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); | 859 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); |
| 566 msg.WriteToLogFile(); | 860 msg.WriteToLogFile(); |
| 567 } | 861 } |
| 568 | 862 |
| 569 | 863 |
| 570 void Logger::StringEvent(const char* name, const char* value) { | 864 void Logger::StringEvent(const char* name, const char* value) { |
| 571 if (FLAG_log) UncheckedStringEvent(name, value); | 865 if (FLAG_log) UncheckedStringEvent(name, value); |
| 572 } | 866 } |
| 573 | 867 |
| 574 | 868 |
| 575 void Logger::UncheckedStringEvent(const char* name, const char* value) { | 869 void Logger::UncheckedStringEvent(const char* name, const char* value) { |
| 576 if (!log_->IsEnabled()) return; | 870 if (!log_->IsEnabled()) return; |
| 577 LogMessageBuilder msg(this); | 871 Log::MessageBuilder msg(log_); |
| 578 msg.Append("%s,\"%s\"\n", name, value); | 872 msg.Append("%s,\"%s\"\n", name, value); |
| 579 msg.WriteToLogFile(); | 873 msg.WriteToLogFile(); |
| 580 } | 874 } |
| 581 | 875 |
| 582 | 876 |
| 583 void Logger::IntEvent(const char* name, int value) { | 877 void Logger::IntEvent(const char* name, int value) { |
| 584 if (FLAG_log) UncheckedIntEvent(name, value); | 878 if (FLAG_log) UncheckedIntEvent(name, value); |
| 585 } | 879 } |
| 586 | 880 |
| 587 | 881 |
| 588 void Logger::IntPtrTEvent(const char* name, intptr_t value) { | 882 void Logger::IntPtrTEvent(const char* name, intptr_t value) { |
| 589 if (FLAG_log) UncheckedIntPtrTEvent(name, value); | 883 if (FLAG_log) UncheckedIntPtrTEvent(name, value); |
| 590 } | 884 } |
| 591 | 885 |
| 592 | 886 |
| 593 void Logger::UncheckedIntEvent(const char* name, int value) { | 887 void Logger::UncheckedIntEvent(const char* name, int value) { |
| 594 if (!log_->IsEnabled()) return; | 888 if (!log_->IsEnabled()) return; |
| 595 LogMessageBuilder msg(this); | 889 Log::MessageBuilder msg(log_); |
| 596 msg.Append("%s,%d\n", name, value); | 890 msg.Append("%s,%d\n", name, value); |
| 597 msg.WriteToLogFile(); | 891 msg.WriteToLogFile(); |
| 598 } | 892 } |
| 599 | 893 |
| 600 | 894 |
| 601 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { | 895 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { |
| 602 if (!log_->IsEnabled()) return; | 896 if (!log_->IsEnabled()) return; |
| 603 LogMessageBuilder msg(this); | 897 Log::MessageBuilder msg(log_); |
| 604 msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value); | 898 msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value); |
| 605 msg.WriteToLogFile(); | 899 msg.WriteToLogFile(); |
| 606 } | 900 } |
| 607 | 901 |
| 608 | 902 |
| 609 void Logger::HandleEvent(const char* name, Object** location) { | 903 void Logger::HandleEvent(const char* name, Object** location) { |
| 610 if (!log_->IsEnabled() || !FLAG_log_handles) return; | 904 if (!log_->IsEnabled() || !FLAG_log_handles) return; |
| 611 LogMessageBuilder msg(this); | 905 Log::MessageBuilder msg(log_); |
| 612 msg.Append("%s,0x%" V8PRIxPTR "\n", name, location); | 906 msg.Append("%s,0x%" V8PRIxPTR "\n", name, location); |
| 613 msg.WriteToLogFile(); | 907 msg.WriteToLogFile(); |
| 614 } | 908 } |
| 615 | 909 |
| 616 | 910 |
| 617 // ApiEvent is private so all the calls come from the Logger class. It is the | 911 // ApiEvent is private so all the calls come from the Logger class. It is the |
| 618 // caller's responsibility to ensure that log is enabled and that | 912 // caller's responsibility to ensure that log is enabled and that |
| 619 // FLAG_log_api is true. | 913 // FLAG_log_api is true. |
| 620 void Logger::ApiEvent(const char* format, ...) { | 914 void Logger::ApiEvent(const char* format, ...) { |
| 621 ASSERT(log_->IsEnabled() && FLAG_log_api); | 915 ASSERT(log_->IsEnabled() && FLAG_log_api); |
| 622 LogMessageBuilder msg(this); | 916 Log::MessageBuilder msg(log_); |
| 623 va_list ap; | 917 va_list ap; |
| 624 va_start(ap, format); | 918 va_start(ap, format); |
| 625 msg.AppendVA(format, ap); | 919 msg.AppendVA(format, ap); |
| 626 va_end(ap); | 920 va_end(ap); |
| 627 msg.WriteToLogFile(); | 921 msg.WriteToLogFile(); |
| 628 } | 922 } |
| 629 | 923 |
| 630 | 924 |
| 631 void Logger::ApiNamedSecurityCheck(Object* key) { | 925 void Logger::ApiNamedSecurityCheck(Object* key) { |
| 632 if (!log_->IsEnabled() || !FLAG_log_api) return; | 926 if (!log_->IsEnabled() || !FLAG_log_api) return; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 651 } else { | 945 } else { |
| 652 ApiEvent("api,check-security,['no-name']\n"); | 946 ApiEvent("api,check-security,['no-name']\n"); |
| 653 } | 947 } |
| 654 } | 948 } |
| 655 | 949 |
| 656 | 950 |
| 657 void Logger::SharedLibraryEvent(const char* library_path, | 951 void Logger::SharedLibraryEvent(const char* library_path, |
| 658 uintptr_t start, | 952 uintptr_t start, |
| 659 uintptr_t end) { | 953 uintptr_t end) { |
| 660 if (!log_->IsEnabled() || !FLAG_prof) return; | 954 if (!log_->IsEnabled() || !FLAG_prof) return; |
| 661 LogMessageBuilder msg(this); | 955 Log::MessageBuilder msg(log_); |
| 662 msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", | 956 msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", |
| 663 library_path, | 957 library_path, |
| 664 start, | 958 start, |
| 665 end); | 959 end); |
| 666 msg.WriteToLogFile(); | 960 msg.WriteToLogFile(); |
| 667 } | 961 } |
| 668 | 962 |
| 669 | 963 |
| 670 void Logger::SharedLibraryEvent(const wchar_t* library_path, | 964 void Logger::SharedLibraryEvent(const wchar_t* library_path, |
| 671 uintptr_t start, | 965 uintptr_t start, |
| 672 uintptr_t end) { | 966 uintptr_t end) { |
| 673 if (!log_->IsEnabled() || !FLAG_prof) return; | 967 if (!log_->IsEnabled() || !FLAG_prof) return; |
| 674 LogMessageBuilder msg(this); | 968 Log::MessageBuilder msg(log_); |
| 675 msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", | 969 msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", |
| 676 library_path, | 970 library_path, |
| 677 start, | 971 start, |
| 678 end); | 972 end); |
| 679 msg.WriteToLogFile(); | 973 msg.WriteToLogFile(); |
| 680 } | 974 } |
| 681 | 975 |
| 682 | 976 |
| 683 void Logger::CodeDeoptEvent(Code* code) { | 977 void Logger::CodeDeoptEvent(Code* code) { |
| 684 if (!log_->IsEnabled()) return; | 978 if (!log_->IsEnabled()) return; |
| 685 ASSERT(FLAG_log_internal_timer_events); | 979 ASSERT(FLAG_log_internal_timer_events); |
| 686 LogMessageBuilder msg(this); | 980 Log::MessageBuilder msg(log_); |
| 687 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); | 981 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); |
| 688 msg.Append("code-deopt,%ld,%d\n", since_epoch, code->CodeSize()); | 982 msg.Append("code-deopt,%ld,%d\n", since_epoch, code->CodeSize()); |
| 689 msg.WriteToLogFile(); | 983 msg.WriteToLogFile(); |
| 690 } | 984 } |
| 691 | 985 |
| 692 | 986 |
| 693 void Logger::TimerEvent(StartEnd se, const char* name) { | 987 void Logger::TimerEvent(StartEnd se, const char* name) { |
| 694 if (!log_->IsEnabled()) return; | 988 if (!log_->IsEnabled()) return; |
| 695 ASSERT(FLAG_log_internal_timer_events); | 989 ASSERT(FLAG_log_internal_timer_events); |
| 696 LogMessageBuilder msg(this); | 990 Log::MessageBuilder msg(log_); |
| 697 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); | 991 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); |
| 698 const char* format = (se == START) ? "timer-event-start,\"%s\",%ld\n" | 992 const char* format = (se == START) ? "timer-event-start,\"%s\",%ld\n" |
| 699 : "timer-event-end,\"%s\",%ld\n"; | 993 : "timer-event-end,\"%s\",%ld\n"; |
| 700 msg.Append(format, name, since_epoch); | 994 msg.Append(format, name, since_epoch); |
| 701 msg.WriteToLogFile(); | 995 msg.WriteToLogFile(); |
| 702 } | 996 } |
| 703 | 997 |
| 704 | 998 |
| 705 void Logger::EnterExternal(Isolate* isolate) { | 999 void Logger::EnterExternal(Isolate* isolate) { |
| 706 LOG(isolate, TimerEvent(START, TimerEventScope::v8_external)); | 1000 LOG(isolate, TimerEvent(START, TimerEventScope::v8_external)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 727 "V8.RecompileParallel"; | 1021 "V8.RecompileParallel"; |
| 728 const char* Logger::TimerEventScope::v8_compile_full_code = | 1022 const char* Logger::TimerEventScope::v8_compile_full_code = |
| 729 "V8.CompileFullCode"; | 1023 "V8.CompileFullCode"; |
| 730 const char* Logger::TimerEventScope::v8_execute = "V8.Execute"; | 1024 const char* Logger::TimerEventScope::v8_execute = "V8.Execute"; |
| 731 const char* Logger::TimerEventScope::v8_external = "V8.External"; | 1025 const char* Logger::TimerEventScope::v8_external = "V8.External"; |
| 732 | 1026 |
| 733 | 1027 |
| 734 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) { | 1028 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) { |
| 735 // Prints "/" + re.source + "/" + | 1029 // Prints "/" + re.source + "/" + |
| 736 // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"") | 1030 // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"") |
| 737 LogMessageBuilder msg(this); | 1031 Log::MessageBuilder msg(log_); |
| 738 | 1032 |
| 739 Handle<Object> source = GetProperty(regexp, "source"); | 1033 Handle<Object> source = GetProperty(regexp, "source"); |
| 740 if (!source->IsString()) { | 1034 if (!source->IsString()) { |
| 741 msg.Append("no source"); | 1035 msg.Append("no source"); |
| 742 return; | 1036 return; |
| 743 } | 1037 } |
| 744 | 1038 |
| 745 switch (regexp->TypeTag()) { | 1039 switch (regexp->TypeTag()) { |
| 746 case JSRegExp::ATOM: | 1040 case JSRegExp::ATOM: |
| 747 msg.Append('a'); | 1041 msg.Append('a'); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 768 if (multiline->IsTrue()) { | 1062 if (multiline->IsTrue()) { |
| 769 msg.Append('m'); | 1063 msg.Append('m'); |
| 770 } | 1064 } |
| 771 | 1065 |
| 772 msg.WriteToLogFile(); | 1066 msg.WriteToLogFile(); |
| 773 } | 1067 } |
| 774 | 1068 |
| 775 | 1069 |
| 776 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { | 1070 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { |
| 777 if (!log_->IsEnabled() || !FLAG_log_regexp) return; | 1071 if (!log_->IsEnabled() || !FLAG_log_regexp) return; |
| 778 LogMessageBuilder msg(this); | 1072 Log::MessageBuilder msg(log_); |
| 779 msg.Append("regexp-compile,"); | 1073 msg.Append("regexp-compile,"); |
| 780 LogRegExpSource(regexp); | 1074 LogRegExpSource(regexp); |
| 781 msg.Append(in_cache ? ",hit\n" : ",miss\n"); | 1075 msg.Append(in_cache ? ",hit\n" : ",miss\n"); |
| 782 msg.WriteToLogFile(); | 1076 msg.WriteToLogFile(); |
| 783 } | 1077 } |
| 784 | 1078 |
| 785 | 1079 |
| 786 void Logger::LogRuntime(Vector<const char> format, | 1080 void Logger::LogRuntime(Vector<const char> format, |
| 787 JSArray* args) { | 1081 JSArray* args) { |
| 788 if (!log_->IsEnabled() || !FLAG_log_runtime) return; | 1082 if (!log_->IsEnabled() || !FLAG_log_runtime) return; |
| 789 HandleScope scope(isolate_); | 1083 HandleScope scope(isolate_); |
| 790 LogMessageBuilder msg(this); | 1084 Log::MessageBuilder msg(log_); |
| 791 for (int i = 0; i < format.length(); i++) { | 1085 for (int i = 0; i < format.length(); i++) { |
| 792 char c = format[i]; | 1086 char c = format[i]; |
| 793 if (c == '%' && i <= format.length() - 2) { | 1087 if (c == '%' && i <= format.length() - 2) { |
| 794 i++; | 1088 i++; |
| 795 ASSERT('0' <= format[i] && format[i] <= '9'); | 1089 ASSERT('0' <= format[i] && format[i] <= '9'); |
| 796 MaybeObject* maybe = args->GetElement(format[i] - '0'); | 1090 MaybeObject* maybe = args->GetElement(format[i] - '0'); |
| 797 Object* obj; | 1091 Object* obj; |
| 798 if (!maybe->ToObject(&obj)) { | 1092 if (!maybe->ToObject(&obj)) { |
| 799 msg.Append("<exception>"); | 1093 msg.Append("<exception>"); |
| 800 continue; | 1094 continue; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 1175 |
| 882 | 1176 |
| 883 void Logger::ApiEntryCall(const char* name) { | 1177 void Logger::ApiEntryCall(const char* name) { |
| 884 if (!log_->IsEnabled() || !FLAG_log_api) return; | 1178 if (!log_->IsEnabled() || !FLAG_log_api) return; |
| 885 ApiEvent("api,%s\n", name); | 1179 ApiEvent("api,%s\n", name); |
| 886 } | 1180 } |
| 887 | 1181 |
| 888 | 1182 |
| 889 void Logger::NewEvent(const char* name, void* object, size_t size) { | 1183 void Logger::NewEvent(const char* name, void* object, size_t size) { |
| 890 if (!log_->IsEnabled() || !FLAG_log) return; | 1184 if (!log_->IsEnabled() || !FLAG_log) return; |
| 891 LogMessageBuilder msg(this); | 1185 Log::MessageBuilder msg(log_); |
| 892 msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object, | 1186 msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object, |
| 893 static_cast<unsigned int>(size)); | 1187 static_cast<unsigned int>(size)); |
| 894 msg.WriteToLogFile(); | 1188 msg.WriteToLogFile(); |
| 895 } | 1189 } |
| 896 | 1190 |
| 897 | 1191 |
| 898 void Logger::DeleteEvent(const char* name, void* object) { | 1192 void Logger::DeleteEvent(const char* name, void* object) { |
| 899 if (!log_->IsEnabled() || !FLAG_log) return; | 1193 if (!log_->IsEnabled() || !FLAG_log) return; |
| 900 LogMessageBuilder msg(this); | 1194 Log::MessageBuilder msg(log_); |
| 901 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); | 1195 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); |
| 902 msg.WriteToLogFile(); | 1196 msg.WriteToLogFile(); |
| 903 } | 1197 } |
| 904 | 1198 |
| 905 | 1199 |
| 906 void Logger::NewEventStatic(const char* name, void* object, size_t size) { | 1200 void Logger::NewEventStatic(const char* name, void* object, size_t size) { |
| 907 Isolate::Current()->logger()->NewEvent(name, object, size); | 1201 Isolate::Current()->logger()->NewEvent(name, object, size); |
| 908 } | 1202 } |
| 909 | 1203 |
| 910 | 1204 |
| 911 void Logger::DeleteEventStatic(const char* name, void* object) { | 1205 void Logger::DeleteEventStatic(const char* name, void* object) { |
| 912 Isolate::Current()->logger()->DeleteEvent(name, object); | 1206 Isolate::Current()->logger()->DeleteEvent(name, object); |
| 913 } | 1207 } |
| 914 | 1208 |
| 1209 |
| 915 void Logger::CallbackEventInternal(const char* prefix, Name* name, | 1210 void Logger::CallbackEventInternal(const char* prefix, Name* name, |
| 916 Address entry_point) { | 1211 Address entry_point) { |
| 917 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1212 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 918 LogMessageBuilder msg(this); | 1213 Log::MessageBuilder msg(log_); |
| 919 msg.Append("%s,%s,-2,", | 1214 msg.Append("%s,%s,-2,", |
| 920 kLogEventsNames[CODE_CREATION_EVENT], | 1215 kLogEventsNames[CODE_CREATION_EVENT], |
| 921 kLogEventsNames[CALLBACK_TAG]); | 1216 kLogEventsNames[CALLBACK_TAG]); |
| 922 msg.AppendAddress(entry_point); | 1217 msg.AppendAddress(entry_point); |
| 923 if (name->IsString()) { | 1218 if (name->IsString()) { |
| 924 SmartArrayPointer<char> str = | 1219 SmartArrayPointer<char> str = |
| 925 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1220 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 926 msg.Append(",1,\"%s%s\"", prefix, *str); | 1221 msg.Append(",1,\"%s%s\"", prefix, *str); |
| 927 } else { | 1222 } else { |
| 928 Symbol* symbol = Symbol::cast(name); | 1223 Symbol* symbol = Symbol::cast(name); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 950 CallbackEventInternal("get ", name, entry_point); | 1245 CallbackEventInternal("get ", name, entry_point); |
| 951 } | 1246 } |
| 952 | 1247 |
| 953 | 1248 |
| 954 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1249 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
| 955 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1250 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 956 CallbackEventInternal("set ", name, entry_point); | 1251 CallbackEventInternal("set ", name, entry_point); |
| 957 } | 1252 } |
| 958 | 1253 |
| 959 | 1254 |
| 960 void Logger::AppendName(Name* name) { | 1255 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
| 961 if (name->IsString()) { | 1256 Logger::LogEventsAndTags tag, |
| 962 name_buffer_->AppendString(String::cast(name)); | 1257 Code* code) { |
| 963 } else { | |
| 964 Symbol* symbol = Symbol::cast(name); | |
| 965 name_buffer_->AppendBytes("symbol("); | |
| 966 if (!symbol->name()->IsUndefined()) { | |
| 967 name_buffer_->AppendBytes("\""); | |
| 968 name_buffer_->AppendString(String::cast(symbol->name())); | |
| 969 name_buffer_->AppendBytes("\" "); | |
| 970 } | |
| 971 name_buffer_->AppendBytes("hash "); | |
| 972 name_buffer_->AppendHex(symbol->Hash()); | |
| 973 name_buffer_->AppendByte(')'); | |
| 974 } | |
| 975 } | |
| 976 | |
| 977 | |
| 978 void Logger::InitNameBuffer(LogEventsAndTags tag) { | |
| 979 name_buffer_->Reset(); | |
| 980 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 981 name_buffer_->AppendByte(':'); | |
| 982 } | |
| 983 | |
| 984 | |
| 985 void Logger::LogRecordedBuffer(Code* code, SharedFunctionInfo* shared) { | |
| 986 if (code_event_handler_ != NULL) { | |
| 987 Script* script = shared && shared->script()->IsScript() ? | |
| 988 Script::cast(shared->script()) : NULL; | |
| 989 IssueCodeAddedEvent(code, | |
| 990 script, | |
| 991 name_buffer_->get(), | |
| 992 name_buffer_->size()); | |
| 993 } | |
| 994 if (!log_->IsEnabled()) return; | |
| 995 LL_LOG(CodeCreateEvent(code, name_buffer_->get(), name_buffer_->size())); | |
| 996 if (Serializer::enabled()) { | |
| 997 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 998 } | |
| 999 } | |
| 1000 | |
| 1001 | |
| 1002 void Logger::AppendCodeCreateHeader(LogMessageBuilder* msg, | |
| 1003 LogEventsAndTags tag, | |
| 1004 Code* code) { | |
| 1005 ASSERT(msg); | 1258 ASSERT(msg); |
| 1006 msg->Append("%s,%s,%d,", | 1259 msg->Append("%s,%s,%d,", |
| 1007 kLogEventsNames[CODE_CREATION_EVENT], | 1260 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
| 1008 kLogEventsNames[tag], | 1261 kLogEventsNames[tag], |
| 1009 code->kind()); | 1262 code->kind()); |
| 1010 msg->AppendAddress(code->address()); | 1263 msg->AppendAddress(code->address()); |
| 1011 msg->Append(",%d,", code->ExecutableSize()); | 1264 msg->Append(",%d,", code->ExecutableSize()); |
| 1012 } | 1265 } |
| 1013 | 1266 |
| 1014 | 1267 |
| 1015 void Logger::AppendSymbolName(LogMessageBuilder* msg, | |
| 1016 Symbol* symbol) { | |
| 1017 ASSERT(symbol); | |
| 1018 msg->Append("symbol("); | |
| 1019 if (!symbol->name()->IsUndefined()) { | |
| 1020 msg->Append("\""); | |
| 1021 msg->AppendDetailed(String::cast(symbol->name()), false); | |
| 1022 msg->Append("\" "); | |
| 1023 } | |
| 1024 msg->Append("hash %x)", symbol->Hash()); | |
| 1025 } | |
| 1026 | |
| 1027 | |
| 1028 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1268 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1029 Code* code, | 1269 Code* code, |
| 1030 const char* comment) { | 1270 const char* comment) { |
| 1031 if (!is_logging_code_events()) return; | 1271 if (!is_logging_code_events()) return; |
| 1032 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1272 |
| 1033 InitNameBuffer(tag); | 1273 JIT_LOG(CodeCreateEvent(tag, code, comment)); |
| 1034 name_buffer_->AppendBytes(comment); | 1274 LL_LOG(CodeCreateEvent(tag, code, comment)); |
| 1035 LogRecordedBuffer(code, NULL); | 1275 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, comment)); |
| 1036 } | |
| 1037 | 1276 |
| 1038 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1277 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1039 LogMessageBuilder msg(this); | 1278 Log::MessageBuilder msg(log_); |
| 1040 AppendCodeCreateHeader(&msg, tag, code); | 1279 AppendCodeCreateHeader(&msg, tag, code); |
| 1041 msg.AppendDoubleQuotedString(comment); | 1280 msg.AppendDoubleQuotedString(comment); |
| 1042 msg.Append('\n'); | 1281 msg.Append('\n'); |
| 1043 msg.WriteToLogFile(); | 1282 msg.WriteToLogFile(); |
| 1044 } | 1283 } |
| 1045 | 1284 |
| 1046 | 1285 |
| 1047 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1286 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1048 Code* code, | 1287 Code* code, |
| 1049 Name* name) { | 1288 Name* name) { |
| 1050 if (!is_logging_code_events()) return; | 1289 if (!is_logging_code_events()) return; |
| 1051 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1290 |
| 1052 InitNameBuffer(tag); | 1291 JIT_LOG(CodeCreateEvent(tag, code, name)); |
| 1053 AppendName(name); | 1292 LL_LOG(CodeCreateEvent(tag, code, name)); |
| 1054 LogRecordedBuffer(code, NULL); | 1293 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, name)); |
| 1055 } | |
| 1056 | 1294 |
| 1057 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1295 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1058 LogMessageBuilder msg(this); | 1296 Log::MessageBuilder msg(log_); |
| 1059 AppendCodeCreateHeader(&msg, tag, code); | 1297 AppendCodeCreateHeader(&msg, tag, code); |
| 1060 if (name->IsString()) { | 1298 if (name->IsString()) { |
| 1061 msg.Append('"'); | 1299 msg.Append('"'); |
| 1062 msg.AppendDetailed(String::cast(name), false); | 1300 msg.AppendDetailed(String::cast(name), false); |
| 1063 msg.Append('"'); | 1301 msg.Append('"'); |
| 1064 } else { | 1302 } else { |
| 1065 AppendSymbolName(&msg, Symbol::cast(name)); | 1303 msg.AppendSymbolName(Symbol::cast(name)); |
| 1066 } | 1304 } |
| 1067 msg.Append('\n'); | 1305 msg.Append('\n'); |
| 1068 msg.WriteToLogFile(); | 1306 msg.WriteToLogFile(); |
| 1069 } | 1307 } |
| 1070 | 1308 |
| 1071 | 1309 |
| 1072 // ComputeMarker must only be used when SharedFunctionInfo is known. | |
| 1073 static const char* ComputeMarker(Code* code) { | |
| 1074 switch (code->kind()) { | |
| 1075 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | |
| 1076 case Code::OPTIMIZED_FUNCTION: return "*"; | |
| 1077 default: return ""; | |
| 1078 } | |
| 1079 } | |
| 1080 | |
| 1081 | |
| 1082 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1310 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1083 Code* code, | 1311 Code* code, |
| 1084 SharedFunctionInfo* shared, | 1312 SharedFunctionInfo* shared, |
| 1085 CompilationInfo* info, | 1313 CompilationInfo* info, |
| 1086 Name* name) { | 1314 Name* name) { |
| 1087 if (!is_logging_code_events()) return; | 1315 if (!is_logging_code_events()) return; |
| 1088 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1316 |
| 1089 InitNameBuffer(tag); | 1317 JIT_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1090 name_buffer_->AppendBytes(ComputeMarker(code)); | 1318 LL_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1091 AppendName(name); | 1319 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1092 LogRecordedBuffer(code, shared); | |
| 1093 } | |
| 1094 | 1320 |
| 1095 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1321 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1096 if (code == isolate_->builtins()->builtin( | 1322 if (code == isolate_->builtins()->builtin( |
| 1097 Builtins::kLazyCompile)) | 1323 Builtins::kLazyCompile)) |
| 1098 return; | 1324 return; |
| 1099 | 1325 |
| 1100 LogMessageBuilder msg(this); | 1326 Log::MessageBuilder msg(log_); |
| 1101 AppendCodeCreateHeader(&msg, tag, code); | 1327 AppendCodeCreateHeader(&msg, tag, code); |
| 1102 if (name->IsString()) { | 1328 if (name->IsString()) { |
| 1103 SmartArrayPointer<char> str = | 1329 SmartArrayPointer<char> str = |
| 1104 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1330 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1105 msg.Append("\"%s\"", *str); | 1331 msg.Append("\"%s\"", *str); |
| 1106 } else { | 1332 } else { |
| 1107 AppendSymbolName(&msg, Symbol::cast(name)); | 1333 msg.AppendSymbolName(Symbol::cast(name)); |
| 1108 } | 1334 } |
| 1109 msg.Append(','); | 1335 msg.Append(','); |
| 1110 msg.AppendAddress(shared->address()); | 1336 msg.AppendAddress(shared->address()); |
| 1111 msg.Append(",%s", ComputeMarker(code)); | 1337 msg.Append(",%s", ComputeMarker(code)); |
| 1112 msg.Append('\n'); | 1338 msg.Append('\n'); |
| 1113 msg.WriteToLogFile(); | 1339 msg.WriteToLogFile(); |
| 1114 } | 1340 } |
| 1115 | 1341 |
| 1116 | 1342 |
| 1117 // Although, it is possible to extract source and line from | 1343 // Although, it is possible to extract source and line from |
| 1118 // the SharedFunctionInfo object, we left it to caller | 1344 // the SharedFunctionInfo object, we left it to caller |
| 1119 // to leave logging functions free from heap allocations. | 1345 // to leave logging functions free from heap allocations. |
| 1120 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1346 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1121 Code* code, | 1347 Code* code, |
| 1122 SharedFunctionInfo* shared, | 1348 SharedFunctionInfo* shared, |
| 1123 CompilationInfo* info, | 1349 CompilationInfo* info, |
| 1124 Name* source, int line) { | 1350 Name* source, int line) { |
| 1125 if (!is_logging_code_events()) return; | 1351 if (!is_logging_code_events()) return; |
| 1126 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1352 |
| 1127 InitNameBuffer(tag); | 1353 JIT_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1128 name_buffer_->AppendBytes(ComputeMarker(code)); | 1354 LL_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1129 name_buffer_->AppendString(shared->DebugName()); | 1355 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1130 name_buffer_->AppendByte(' '); | |
| 1131 if (source->IsString()) { | |
| 1132 name_buffer_->AppendString(String::cast(source)); | |
| 1133 } else { | |
| 1134 name_buffer_->AppendBytes("symbol(hash "); | |
| 1135 name_buffer_->AppendHex(Name::cast(source)->Hash()); | |
| 1136 name_buffer_->AppendByte(')'); | |
| 1137 } | |
| 1138 name_buffer_->AppendByte(':'); | |
| 1139 name_buffer_->AppendInt(line); | |
| 1140 LogRecordedBuffer(code, shared); | |
| 1141 } | |
| 1142 | 1356 |
| 1143 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1357 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1144 LogMessageBuilder msg(this); | 1358 Log::MessageBuilder msg(log_); |
| 1145 AppendCodeCreateHeader(&msg, tag, code); | 1359 AppendCodeCreateHeader(&msg, tag, code); |
| 1146 SmartArrayPointer<char> name = | 1360 SmartArrayPointer<char> name = |
| 1147 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1361 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1148 msg.Append("\"%s ", *name); | 1362 msg.Append("\"%s ", *name); |
| 1149 if (source->IsString()) { | 1363 if (source->IsString()) { |
| 1150 SmartArrayPointer<char> sourcestr = | 1364 SmartArrayPointer<char> sourcestr = |
| 1151 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1365 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1152 msg.Append("%s", *sourcestr); | 1366 msg.Append("%s", *sourcestr); |
| 1153 } else { | 1367 } else { |
| 1154 AppendSymbolName(&msg, Symbol::cast(source)); | 1368 msg.AppendSymbolName(Symbol::cast(source)); |
| 1155 } | 1369 } |
| 1156 msg.Append(":%d\",", line); | 1370 msg.Append(":%d\",", line); |
| 1157 msg.AppendAddress(shared->address()); | 1371 msg.AppendAddress(shared->address()); |
| 1158 msg.Append(",%s", ComputeMarker(code)); | 1372 msg.Append(",%s", ComputeMarker(code)); |
| 1159 msg.Append('\n'); | 1373 msg.Append('\n'); |
| 1160 msg.WriteToLogFile(); | 1374 msg.WriteToLogFile(); |
| 1161 } | 1375 } |
| 1162 | 1376 |
| 1163 | 1377 |
| 1164 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { | 1378 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1379 Code* code, |
| 1380 int args_count) { |
| 1165 if (!is_logging_code_events()) return; | 1381 if (!is_logging_code_events()) return; |
| 1166 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1382 |
| 1167 InitNameBuffer(tag); | 1383 JIT_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1168 name_buffer_->AppendInt(args_count); | 1384 LL_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1169 LogRecordedBuffer(code, NULL); | 1385 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1170 } | |
| 1171 | 1386 |
| 1172 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1387 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1173 LogMessageBuilder msg(this); | 1388 Log::MessageBuilder msg(log_); |
| 1174 AppendCodeCreateHeader(&msg, tag, code); | 1389 AppendCodeCreateHeader(&msg, tag, code); |
| 1175 msg.Append("\"args_count: %d\"", args_count); | 1390 msg.Append("\"args_count: %d\"", args_count); |
| 1176 msg.Append('\n'); | 1391 msg.Append('\n'); |
| 1177 msg.WriteToLogFile(); | 1392 msg.WriteToLogFile(); |
| 1178 } | 1393 } |
| 1179 | 1394 |
| 1180 | 1395 |
| 1181 void Logger::CodeMovingGCEvent() { | 1396 void Logger::CodeMovingGCEvent() { |
| 1182 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1397 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1183 LL_LOG(CodeMovingGCEvent()); | 1398 LL_LOG(CodeMovingGCEvent()); |
| 1184 OS::SignalCodeMovingGC(); | 1399 OS::SignalCodeMovingGC(); |
| 1185 } | 1400 } |
| 1186 | 1401 |
| 1187 | 1402 |
| 1188 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1403 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 1189 if (!is_logging_code_events()) return; | 1404 if (!is_logging_code_events()) return; |
| 1190 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1405 |
| 1191 InitNameBuffer(REG_EXP_TAG); | 1406 JIT_LOG(RegExpCodeCreateEvent(code, source)); |
| 1192 name_buffer_->AppendString(source); | 1407 LL_LOG(RegExpCodeCreateEvent(code, source)); |
| 1193 LogRecordedBuffer(code, NULL); | 1408 CODE_ADDRESS_MAP_LOG(RegExpCodeCreateEvent(code, source)); |
| 1194 } | |
| 1195 | 1409 |
| 1196 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1410 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1197 LogMessageBuilder msg(this); | 1411 Log::MessageBuilder msg(log_); |
| 1198 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1412 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1199 msg.Append('"'); | 1413 msg.Append('"'); |
| 1200 msg.AppendDetailed(source, false); | 1414 msg.AppendDetailed(source, false); |
| 1201 msg.Append('"'); | 1415 msg.Append('"'); |
| 1202 msg.Append('\n'); | 1416 msg.Append('\n'); |
| 1203 msg.WriteToLogFile(); | 1417 msg.WriteToLogFile(); |
| 1204 } | 1418 } |
| 1205 | 1419 |
| 1206 | 1420 |
| 1207 void Logger::CodeMoveEvent(Address from, Address to) { | 1421 void Logger::CodeMoveEvent(Address from, Address to) { |
| 1208 if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to); | 1422 JIT_LOG(CodeMovedEvent(from, to)); |
| 1209 if (!log_->IsEnabled()) return; | 1423 if (!log_->IsEnabled()) return; |
| 1210 LL_LOG(CodeMoveEvent(from, to)); | 1424 LL_LOG(CodeMoveEvent(from, to)); |
| 1211 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1425 CODE_ADDRESS_MAP_LOG(CodeMoveEvent(from, to)); |
| 1212 address_to_name_map_->Move(from, to); | |
| 1213 } | |
| 1214 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1426 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| 1215 } | 1427 } |
| 1216 | 1428 |
| 1217 | 1429 |
| 1218 void Logger::CodeDeleteEvent(Address from) { | 1430 void Logger::CodeDeleteEvent(Address from) { |
| 1219 if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from); | 1431 JIT_LOG(CodeDeleteEvent(from)); |
| 1220 if (!log_->IsEnabled()) return; | 1432 if (!log_->IsEnabled()) return; |
| 1221 LL_LOG(CodeDeleteEvent(from)); | 1433 LL_LOG(CodeDeleteEvent(from)); |
| 1222 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1434 CODE_ADDRESS_MAP_LOG(CodeDeleteEvent(from)); |
| 1223 address_to_name_map_->Remove(from); | 1435 |
| 1224 } | 1436 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 1225 DeleteEventInternal(CODE_DELETE_EVENT, from); | 1437 Log::MessageBuilder msg(log_); |
| 1438 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); |
| 1439 msg.AppendAddress(from); |
| 1440 msg.Append('\n'); |
| 1441 msg.WriteToLogFile(); |
| 1226 } | 1442 } |
| 1227 | 1443 |
| 1444 |
| 1228 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1445 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1229 int pc_offset, | 1446 int pc_offset, |
| 1230 int position) { | 1447 int position) { |
| 1231 if (code_event_handler_ != NULL) { | 1448 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1232 IssueAddCodeLinePosInfoEvent(jit_handler_data, | 1449 pc_offset, |
| 1233 pc_offset, | 1450 position, |
| 1234 position, | 1451 JitCodeEvent::POSITION)); |
| 1235 JitCodeEvent::POSITION); | |
| 1236 } | |
| 1237 } | 1452 } |
| 1238 | 1453 |
| 1454 |
| 1239 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, | 1455 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, |
| 1240 int pc_offset, | 1456 int pc_offset, |
| 1241 int position) { | 1457 int position) { |
| 1242 if (code_event_handler_ != NULL) { | 1458 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1243 IssueAddCodeLinePosInfoEvent(jit_handler_data, | 1459 pc_offset, |
| 1244 pc_offset, | 1460 position, |
| 1245 position, | 1461 JitCodeEvent::STATEMENT_POSITION)); |
| 1246 JitCodeEvent::STATEMENT_POSITION); | 1462 } |
| 1463 |
| 1464 |
| 1465 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { |
| 1466 if (jit_logger_ != NULL) { |
| 1467 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); |
| 1247 } | 1468 } |
| 1248 } | 1469 } |
| 1249 | 1470 |
| 1250 | 1471 |
| 1251 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { | |
| 1252 if (code_event_handler_ != NULL) { | |
| 1253 pos_recorder->AttachJITHandlerData(IssueStartCodePosInfoEvent()); | |
| 1254 } | |
| 1255 } | |
| 1256 | |
| 1257 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | 1472 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, |
| 1258 void* jit_handler_data) { | 1473 void* jit_handler_data) { |
| 1259 if (code_event_handler_ != NULL) { | 1474 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
| 1260 IssueEndCodePosInfoEvent(code, jit_handler_data); | |
| 1261 } | |
| 1262 } | 1475 } |
| 1263 | 1476 |
| 1264 | 1477 |
| 1265 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1478 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| 1266 if (!log_->IsEnabled()) return; | 1479 if (!log_->IsEnabled()) return; |
| 1267 LL_LOG(SnapshotPositionEvent(addr, pos)); | 1480 LL_LOG(SnapshotPositionEvent(addr, pos)); |
| 1268 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1481 if (Serializer::enabled()) { |
| 1269 const char* code_name = address_to_name_map_->Lookup(addr); | 1482 const char* code_name = code_address_map_->Lookup(addr); |
| 1270 if (code_name == NULL) return; // Not a code object. | 1483 if (code_name == NULL) return; // Not a code object. |
| 1271 LogMessageBuilder msg(this); | 1484 Log::MessageBuilder msg(log_); |
| 1272 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | 1485 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1273 msg.AppendDoubleQuotedString(code_name); | 1486 msg.AppendDoubleQuotedString(code_name); |
| 1274 msg.Append("\n"); | 1487 msg.Append("\n"); |
| 1275 msg.WriteToLogFile(); | 1488 msg.WriteToLogFile(); |
| 1276 } | 1489 } |
| 1277 if (!FLAG_log_snapshot_positions) return; | 1490 if (!FLAG_log_snapshot_positions) return; |
| 1278 LogMessageBuilder msg(this); | 1491 Log::MessageBuilder msg(log_); |
| 1279 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 1492 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| 1280 msg.AppendAddress(addr); | 1493 msg.AppendAddress(addr); |
| 1281 msg.Append(",%d", pos); | 1494 msg.Append(",%d", pos); |
| 1282 msg.Append('\n'); | 1495 msg.Append('\n'); |
| 1283 msg.WriteToLogFile(); | 1496 msg.WriteToLogFile(); |
| 1284 } | 1497 } |
| 1285 | 1498 |
| 1286 | 1499 |
| 1287 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { | 1500 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { |
| 1288 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); | 1501 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); |
| 1289 } | 1502 } |
| 1290 | 1503 |
| 1291 | 1504 |
| 1292 void Logger::MoveEventInternal(LogEventsAndTags event, | 1505 void Logger::MoveEventInternal(LogEventsAndTags event, |
| 1293 Address from, | 1506 Address from, |
| 1294 Address to) { | 1507 Address to) { |
| 1295 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1508 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 1296 LogMessageBuilder msg(this); | 1509 Log::MessageBuilder msg(log_); |
| 1297 msg.Append("%s,", kLogEventsNames[event]); | 1510 msg.Append("%s,", kLogEventsNames[event]); |
| 1298 msg.AppendAddress(from); | 1511 msg.AppendAddress(from); |
| 1299 msg.Append(','); | 1512 msg.Append(','); |
| 1300 msg.AppendAddress(to); | 1513 msg.AppendAddress(to); |
| 1301 msg.Append('\n'); | 1514 msg.Append('\n'); |
| 1302 msg.WriteToLogFile(); | 1515 msg.WriteToLogFile(); |
| 1303 } | 1516 } |
| 1304 | 1517 |
| 1305 | 1518 |
| 1306 void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) { | |
| 1307 if (!log_->IsEnabled() || !FLAG_log_code) return; | |
| 1308 LogMessageBuilder msg(this); | |
| 1309 msg.Append("%s,", kLogEventsNames[event]); | |
| 1310 msg.AppendAddress(from); | |
| 1311 msg.Append('\n'); | |
| 1312 msg.WriteToLogFile(); | |
| 1313 } | |
| 1314 | |
| 1315 | |
| 1316 void Logger::ResourceEvent(const char* name, const char* tag) { | 1519 void Logger::ResourceEvent(const char* name, const char* tag) { |
| 1317 if (!log_->IsEnabled() || !FLAG_log) return; | 1520 if (!log_->IsEnabled() || !FLAG_log) return; |
| 1318 LogMessageBuilder msg(this); | 1521 Log::MessageBuilder msg(log_); |
| 1319 msg.Append("%s,%s,", name, tag); | 1522 msg.Append("%s,%s,", name, tag); |
| 1320 | 1523 |
| 1321 uint32_t sec, usec; | 1524 uint32_t sec, usec; |
| 1322 if (OS::GetUserTime(&sec, &usec) != -1) { | 1525 if (OS::GetUserTime(&sec, &usec) != -1) { |
| 1323 msg.Append("%d,%d,", sec, usec); | 1526 msg.Append("%d,%d,", sec, usec); |
| 1324 } | 1527 } |
| 1325 msg.Append("%.0f", OS::TimeCurrentMillis()); | 1528 msg.Append("%.0f", OS::TimeCurrentMillis()); |
| 1326 | 1529 |
| 1327 msg.Append('\n'); | 1530 msg.Append('\n'); |
| 1328 msg.WriteToLogFile(); | 1531 msg.WriteToLogFile(); |
| 1329 } | 1532 } |
| 1330 | 1533 |
| 1331 | 1534 |
| 1332 void Logger::SuspectReadEvent(Name* name, Object* obj) { | 1535 void Logger::SuspectReadEvent(Name* name, Object* obj) { |
| 1333 if (!log_->IsEnabled() || !FLAG_log_suspect) return; | 1536 if (!log_->IsEnabled() || !FLAG_log_suspect) return; |
| 1334 LogMessageBuilder msg(this); | 1537 Log::MessageBuilder msg(log_); |
| 1335 String* class_name = obj->IsJSObject() | 1538 String* class_name = obj->IsJSObject() |
| 1336 ? JSObject::cast(obj)->class_name() | 1539 ? JSObject::cast(obj)->class_name() |
| 1337 : isolate_->heap()->empty_string(); | 1540 : isolate_->heap()->empty_string(); |
| 1338 msg.Append("suspect-read,"); | 1541 msg.Append("suspect-read,"); |
| 1339 msg.Append(class_name); | 1542 msg.Append(class_name); |
| 1340 msg.Append(','); | 1543 msg.Append(','); |
| 1341 if (name->IsString()) { | 1544 if (name->IsString()) { |
| 1342 msg.Append('"'); | 1545 msg.Append('"'); |
| 1343 msg.Append(String::cast(name)); | 1546 msg.Append(String::cast(name)); |
| 1344 msg.Append('"'); | 1547 msg.Append('"'); |
| 1345 } else { | 1548 } else { |
| 1346 AppendSymbolName(&msg, Symbol::cast(name)); | 1549 msg.AppendSymbolName(Symbol::cast(name)); |
| 1347 } | 1550 } |
| 1348 msg.Append('\n'); | 1551 msg.Append('\n'); |
| 1349 msg.WriteToLogFile(); | 1552 msg.WriteToLogFile(); |
| 1350 } | 1553 } |
| 1351 | 1554 |
| 1352 | 1555 |
| 1353 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) { | 1556 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) { |
| 1354 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1557 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
| 1355 LogMessageBuilder msg(this); | 1558 Log::MessageBuilder msg(log_); |
| 1356 // Using non-relative system time in order to be able to synchronize with | 1559 // Using non-relative system time in order to be able to synchronize with |
| 1357 // external memory profiling events (e.g. DOM memory size). | 1560 // external memory profiling events (e.g. DOM memory size). |
| 1358 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", | 1561 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", |
| 1359 space, kind, OS::TimeCurrentMillis()); | 1562 space, kind, OS::TimeCurrentMillis()); |
| 1360 msg.WriteToLogFile(); | 1563 msg.WriteToLogFile(); |
| 1361 } | 1564 } |
| 1362 | 1565 |
| 1363 | 1566 |
| 1364 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { | 1567 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { |
| 1365 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1568 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
| 1366 LogMessageBuilder msg(this); | 1569 Log::MessageBuilder msg(log_); |
| 1367 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); | 1570 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); |
| 1368 msg.WriteToLogFile(); | 1571 msg.WriteToLogFile(); |
| 1369 } | 1572 } |
| 1370 | 1573 |
| 1371 | 1574 |
| 1372 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { | 1575 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { |
| 1373 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1576 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
| 1374 LogMessageBuilder msg(this); | 1577 Log::MessageBuilder msg(log_); |
| 1375 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); | 1578 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); |
| 1376 msg.WriteToLogFile(); | 1579 msg.WriteToLogFile(); |
| 1377 } | 1580 } |
| 1378 | 1581 |
| 1379 | 1582 |
| 1380 void Logger::DebugTag(const char* call_site_tag) { | 1583 void Logger::DebugTag(const char* call_site_tag) { |
| 1381 if (!log_->IsEnabled() || !FLAG_log) return; | 1584 if (!log_->IsEnabled() || !FLAG_log) return; |
| 1382 LogMessageBuilder msg(this); | 1585 Log::MessageBuilder msg(log_); |
| 1383 msg.Append("debug-tag,%s\n", call_site_tag); | 1586 msg.Append("debug-tag,%s\n", call_site_tag); |
| 1384 msg.WriteToLogFile(); | 1587 msg.WriteToLogFile(); |
| 1385 } | 1588 } |
| 1386 | 1589 |
| 1387 | 1590 |
| 1388 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { | 1591 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { |
| 1389 if (!log_->IsEnabled() || !FLAG_log) return; | 1592 if (!log_->IsEnabled() || !FLAG_log) return; |
| 1390 StringBuilder s(parameter.length() + 1); | 1593 StringBuilder s(parameter.length() + 1); |
| 1391 for (int i = 0; i < parameter.length(); ++i) { | 1594 for (int i = 0; i < parameter.length(); ++i) { |
| 1392 s.AddCharacter(static_cast<char>(parameter[i])); | 1595 s.AddCharacter(static_cast<char>(parameter[i])); |
| 1393 } | 1596 } |
| 1394 char* parameter_string = s.Finalize(); | 1597 char* parameter_string = s.Finalize(); |
| 1395 LogMessageBuilder msg(this); | 1598 Log::MessageBuilder msg(log_); |
| 1396 msg.Append("debug-queue-event,%s,%15.3f,%s\n", | 1599 msg.Append("debug-queue-event,%s,%15.3f,%s\n", |
| 1397 event_type, | 1600 event_type, |
| 1398 OS::TimeCurrentMillis(), | 1601 OS::TimeCurrentMillis(), |
| 1399 parameter_string); | 1602 parameter_string); |
| 1400 DeleteArray(parameter_string); | 1603 DeleteArray(parameter_string); |
| 1401 msg.WriteToLogFile(); | 1604 msg.WriteToLogFile(); |
| 1402 } | 1605 } |
| 1403 | 1606 |
| 1404 | 1607 |
| 1405 void Logger::TickEvent(TickSample* sample, bool overflow) { | 1608 void Logger::TickEvent(TickSample* sample, bool overflow) { |
| 1406 if (!log_->IsEnabled() || !FLAG_prof) return; | 1609 if (!log_->IsEnabled() || !FLAG_prof) return; |
| 1407 LogMessageBuilder msg(this); | 1610 Log::MessageBuilder msg(log_); |
| 1408 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); | 1611 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); |
| 1409 msg.AppendAddress(sample->pc); | 1612 msg.AppendAddress(sample->pc); |
| 1410 msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_)); | 1613 msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_)); |
| 1411 if (sample->has_external_callback) { | 1614 if (sample->has_external_callback) { |
| 1412 msg.Append(",1,"); | 1615 msg.Append(",1,"); |
| 1413 msg.AppendAddress(sample->external_callback); | 1616 msg.AppendAddress(sample->external_callback); |
| 1414 } else { | 1617 } else { |
| 1415 msg.Append(",0,"); | 1618 msg.Append(",0,"); |
| 1416 msg.AppendAddress(sample->tos); | 1619 msg.AppendAddress(sample->tos); |
| 1417 } | 1620 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 description = "A keyed call IC from the snapshot"; | 1798 description = "A keyed call IC from the snapshot"; |
| 1596 tag = Logger::KEYED_CALL_IC_TAG; | 1799 tag = Logger::KEYED_CALL_IC_TAG; |
| 1597 break; | 1800 break; |
| 1598 case Code::NUMBER_OF_KINDS: | 1801 case Code::NUMBER_OF_KINDS: |
| 1599 break; | 1802 break; |
| 1600 } | 1803 } |
| 1601 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); | 1804 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); |
| 1602 } | 1805 } |
| 1603 | 1806 |
| 1604 | 1807 |
| 1605 void Logger::RegisterSnapshotCodeName(Code* code, | |
| 1606 const char* name, | |
| 1607 int name_size) { | |
| 1608 ASSERT(Serializer::enabled()); | |
| 1609 if (address_to_name_map_ == NULL) { | |
| 1610 address_to_name_map_ = new NameMap; | |
| 1611 } | |
| 1612 address_to_name_map_->Insert(code->address(), name, name_size); | |
| 1613 } | |
| 1614 | |
| 1615 | |
| 1616 LowLevelLogger::LowLevelLogger(const char* name) | |
| 1617 : ll_output_handle_(NULL) { | |
| 1618 // Open the low-level log file. | |
| 1619 size_t len = strlen(name); | |
| 1620 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt))); | |
| 1621 OS::MemCopy(ll_name.start(), name, len); | |
| 1622 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt)); | |
| 1623 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); | |
| 1624 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize); | |
| 1625 | |
| 1626 LogCodeInfo(); | |
| 1627 } | |
| 1628 | |
| 1629 | |
| 1630 LowLevelLogger::~LowLevelLogger() { | |
| 1631 fclose(ll_output_handle_); | |
| 1632 ll_output_handle_ = NULL; | |
| 1633 } | |
| 1634 | |
| 1635 | |
| 1636 void LowLevelLogger::LogCodeInfo() { | |
| 1637 #if V8_TARGET_ARCH_IA32 | |
| 1638 const char arch[] = "ia32"; | |
| 1639 #elif V8_TARGET_ARCH_X64 | |
| 1640 const char arch[] = "x64"; | |
| 1641 #elif V8_TARGET_ARCH_ARM | |
| 1642 const char arch[] = "arm"; | |
| 1643 #elif V8_TARGET_ARCH_MIPS | |
| 1644 const char arch[] = "mips"; | |
| 1645 #else | |
| 1646 const char arch[] = "unknown"; | |
| 1647 #endif | |
| 1648 LogWriteBytes(arch, sizeof(arch)); | |
| 1649 } | |
| 1650 | |
| 1651 void LowLevelLogger::CodeCreateEvent(Code* code, | |
| 1652 const char* name, | |
| 1653 int name_size) { | |
| 1654 CodeCreateStruct event; | |
| 1655 event.name_size = name_size; | |
| 1656 event.code_address = code->instruction_start(); | |
| 1657 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | |
| 1658 event.code_size = code->instruction_size(); | |
| 1659 LogWriteStruct(event); | |
| 1660 LogWriteBytes(name, name_size); | |
| 1661 LogWriteBytes( | |
| 1662 reinterpret_cast<const char*>(code->instruction_start()), | |
| 1663 code->instruction_size()); | |
| 1664 } | |
| 1665 | |
| 1666 | |
| 1667 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | |
| 1668 CodeMoveStruct event; | |
| 1669 event.from_address = from + Code::kHeaderSize; | |
| 1670 event.to_address = to + Code::kHeaderSize; | |
| 1671 LogWriteStruct(event); | |
| 1672 } | |
| 1673 | |
| 1674 | |
| 1675 void LowLevelLogger::CodeDeleteEvent(Address from) { | |
| 1676 CodeDeleteStruct event; | |
| 1677 event.address = from + Code::kHeaderSize; | |
| 1678 LogWriteStruct(event); | |
| 1679 } | |
| 1680 | |
| 1681 | |
| 1682 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { | |
| 1683 SnapshotPositionStruct event; | |
| 1684 event.address = addr + Code::kHeaderSize; | |
| 1685 event.position = pos; | |
| 1686 LogWriteStruct(event); | |
| 1687 } | |
| 1688 | |
| 1689 | |
| 1690 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { | |
| 1691 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); | |
| 1692 ASSERT(static_cast<size_t>(size) == rv); | |
| 1693 USE(rv); | |
| 1694 } | |
| 1695 | |
| 1696 | |
| 1697 void LowLevelLogger::CodeMovingGCEvent() { | |
| 1698 const char tag = kCodeMovingGCTag; | |
| 1699 | |
| 1700 LogWriteBytes(&tag, sizeof(tag)); | |
| 1701 } | |
| 1702 | |
| 1703 | |
| 1704 void Logger::LogCodeObjects() { | 1808 void Logger::LogCodeObjects() { |
| 1705 Heap* heap = isolate_->heap(); | 1809 Heap* heap = isolate_->heap(); |
| 1706 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1810 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1707 "Logger::LogCodeObjects"); | 1811 "Logger::LogCodeObjects"); |
| 1708 HeapIterator iterator(heap); | 1812 HeapIterator iterator(heap); |
| 1709 DisallowHeapAllocation no_gc; | 1813 DisallowHeapAllocation no_gc; |
| 1710 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1814 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1711 if (obj->IsCode()) LogCodeObject(obj); | 1815 if (obj->IsCode()) LogCodeObject(obj); |
| 1712 } | 1816 } |
| 1713 } | 1817 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 } | 2007 } |
| 1904 | 2008 |
| 1905 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); | 2009 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); |
| 1906 | 2010 |
| 1907 return true; | 2011 return true; |
| 1908 } | 2012 } |
| 1909 | 2013 |
| 1910 | 2014 |
| 1911 void Logger::SetCodeEventHandler(uint32_t options, | 2015 void Logger::SetCodeEventHandler(uint32_t options, |
| 1912 JitCodeEventHandler event_handler) { | 2016 JitCodeEventHandler event_handler) { |
| 1913 code_event_handler_ = event_handler; | 2017 if (jit_logger_) { |
| 2018 delete jit_logger_; |
| 2019 jit_logger_ = NULL; |
| 2020 } |
| 1914 | 2021 |
| 1915 if (code_event_handler_ != NULL && (options & kJitCodeEventEnumExisting)) { | 2022 if (event_handler) { |
| 2023 jit_logger_ = new JitLogger(event_handler); |
| 2024 } |
| 2025 |
| 2026 if (jit_logger_ != NULL && (options & kJitCodeEventEnumExisting)) { |
| 1916 HandleScope scope(isolate_); | 2027 HandleScope scope(isolate_); |
| 1917 LogCodeObjects(); | 2028 LogCodeObjects(); |
| 1918 LogCompiledFunctions(); | 2029 LogCompiledFunctions(); |
| 1919 } | 2030 } |
| 1920 } | 2031 } |
| 1921 | 2032 |
| 1922 | 2033 |
| 1923 Sampler* Logger::sampler() { | 2034 Sampler* Logger::sampler() { |
| 1924 return ticker_; | 2035 return ticker_; |
| 1925 } | 2036 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1937 } | 2048 } |
| 1938 | 2049 |
| 1939 delete ticker_; | 2050 delete ticker_; |
| 1940 ticker_ = NULL; | 2051 ticker_ = NULL; |
| 1941 | 2052 |
| 1942 if (ll_logger_) { | 2053 if (ll_logger_) { |
| 1943 delete ll_logger_; | 2054 delete ll_logger_; |
| 1944 ll_logger_ = NULL; | 2055 ll_logger_ = NULL; |
| 1945 } | 2056 } |
| 1946 | 2057 |
| 2058 if (jit_logger_) { |
| 2059 delete jit_logger_; |
| 2060 jit_logger_ = NULL; |
| 2061 } |
| 2062 |
| 1947 return log_->Close(); | 2063 return log_->Close(); |
| 1948 } | 2064 } |
| 1949 | 2065 |
| 1950 } } // namespace v8::internal | 2066 } } // namespace v8::internal |
| OLD | NEW |