| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 void Profiler::Run() { | 252 void Profiler::Run() { |
| 253 TickSample sample; | 253 TickSample sample; |
| 254 bool overflow = Logger::profiler_->Remove(&sample); | 254 bool overflow = Logger::profiler_->Remove(&sample); |
| 255 while (running_) { | 255 while (running_) { |
| 256 LOG(TickEvent(&sample, overflow)); | 256 LOG(TickEvent(&sample, overflow)); |
| 257 overflow = Logger::profiler_->Remove(&sample); | 257 overflow = Logger::profiler_->Remove(&sample); |
| 258 } | 258 } |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 263 // Utility class for formatting log messages. It fills the message into the |
| 264 // static buffer in Logger. |
| 265 class LogMessageBuilder BASE_EMBEDDED { |
| 266 public: |
| 267 explicit LogMessageBuilder(); |
| 268 ~LogMessageBuilder() { } |
| 269 |
| 270 void Append(const char* format, ...); |
| 271 void Append(const char c); |
| 272 |
| 273 void WriteToLogFile(); |
| 274 |
| 275 private: |
| 276 ScopedLock sl; |
| 277 int pos_; |
| 278 }; |
| 279 |
| 280 |
| 281 // Create a message builder starting from position 0. This acquires the mutex |
| 282 // in the logger as well. |
| 283 LogMessageBuilder::LogMessageBuilder(): pos_(0), sl(Logger::mutex_) { |
| 284 ASSERT(Logger::message_buffer_ != NULL); |
| 285 } |
| 286 |
| 287 |
| 288 // Append string data to the log message. |
| 289 void LogMessageBuilder::Append(const char* format, ...) { |
| 290 Vector<char> buf(Logger::message_buffer_ + pos_, |
| 291 Logger::kMessageBufferSize - pos_); |
| 292 va_list args; |
| 293 va_start(args, format); |
| 294 int result = v8::internal::OS::VSNPrintF(buf, format, args); |
| 295 va_end(args); |
| 296 |
| 297 // Result is -1 if output was truncated. |
| 298 if (result >= 0) { |
| 299 pos_ += result; |
| 300 } else { |
| 301 pos_ = Logger::kMessageBufferSize; |
| 302 } |
| 303 ASSERT(pos_ <= Logger::kMessageBufferSize); |
| 304 } |
| 305 |
| 306 |
| 307 // Append a character to the log message. |
| 308 void LogMessageBuilder::Append(const char c) { |
| 309 if (pos_ < Logger::kMessageBufferSize) { |
| 310 Logger::message_buffer_[pos_++] = c; |
| 311 } |
| 312 ASSERT(pos_ <= Logger::kMessageBufferSize); |
| 313 } |
| 314 |
| 315 |
| 316 // Write the log message to the log file currently opened. |
| 317 void LogMessageBuilder::WriteToLogFile() { |
| 318 ASSERT(pos_ <= Logger::kMessageBufferSize); |
| 319 fwrite(Logger::message_buffer_, 1, pos_, Logger::logfile_); |
| 320 } |
| 321 #endif |
| 322 |
| 323 |
| 262 // | 324 // |
| 263 // Logger class implementation. | 325 // Logger class implementation. |
| 264 // | 326 // |
| 265 Ticker* Logger::ticker_ = NULL; | 327 Ticker* Logger::ticker_ = NULL; |
| 328 char* Logger::message_buffer_ = NULL; |
| 266 FILE* Logger::logfile_ = NULL; | 329 FILE* Logger::logfile_ = NULL; |
| 267 Profiler* Logger::profiler_ = NULL; | 330 Profiler* Logger::profiler_ = NULL; |
| 268 Mutex* Logger::mutex_ = NULL; | 331 Mutex* Logger::mutex_ = NULL; |
| 269 VMState* Logger::current_state_ = NULL; | 332 VMState* Logger::current_state_ = NULL; |
| 270 SlidingStateWindow* Logger::sliding_state_window_ = NULL; | 333 SlidingStateWindow* Logger::sliding_state_window_ = NULL; |
| 271 | 334 |
| 272 #endif // ENABLE_LOGGING_AND_PROFILING | 335 #endif // ENABLE_LOGGING_AND_PROFILING |
| 273 | 336 |
| 337 |
| 274 void Logger::Preamble(const char* content) { | 338 void Logger::Preamble(const char* content) { |
| 275 #ifdef ENABLE_LOGGING_AND_PROFILING | 339 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 276 if (logfile_ == NULL || !FLAG_log_code) return; | 340 if (logfile_ == NULL || !FLAG_log_code) return; |
| 277 ScopedLock sl(mutex_); | 341 ScopedLock sl(mutex_); |
| 278 fprintf(logfile_, "%s", content); | 342 fprintf(logfile_, "%s", content); |
| 279 #endif | 343 #endif |
| 280 } | 344 } |
| 281 | 345 |
| 282 | 346 |
| 283 void Logger::StringEvent(const char* name, const char* value) { | 347 void Logger::StringEvent(const char* name, const char* value) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 ScopedLock sl(mutex_); | 625 ScopedLock sl(mutex_); |
| 562 fprintf(logfile_, "delete,%s,0x%x\n", name, | 626 fprintf(logfile_, "delete,%s,0x%x\n", name, |
| 563 reinterpret_cast<unsigned int>(object)); | 627 reinterpret_cast<unsigned int>(object)); |
| 564 #endif | 628 #endif |
| 565 } | 629 } |
| 566 | 630 |
| 567 | 631 |
| 568 void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) { | 632 void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) { |
| 569 #ifdef ENABLE_LOGGING_AND_PROFILING | 633 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 570 if (logfile_ == NULL || !FLAG_log_code) return; | 634 if (logfile_ == NULL || !FLAG_log_code) return; |
| 571 ScopedLock sl(mutex_); | 635 LogMessageBuilder msg; |
| 572 | 636 msg.Append("code-creation,%s,0x%x,%d,\"", tag, |
| 573 fprintf(logfile_, "code-creation,%s,0x%x,%d,\"", tag, | 637 reinterpret_cast<unsigned int>(code->address()), |
| 574 reinterpret_cast<unsigned int>(code->address()), | 638 code->instruction_size()); |
| 575 code->instruction_size()); | |
| 576 for (const char* p = comment; *p != '\0'; p++) { | 639 for (const char* p = comment; *p != '\0'; p++) { |
| 577 if (*p == '\"') fprintf(logfile_, "\\"); | 640 if (*p == '\"') fprintf(logfile_, "\\"); |
| 578 fprintf(logfile_, "%c", *p); | 641 msg.Append(*p); |
| 579 } | 642 } |
| 580 fprintf(logfile_, "\"\n"); | 643 msg.Append('"'); |
| 644 msg.Append('\n'); |
| 645 msg.WriteToLogFile(); |
| 581 #endif | 646 #endif |
| 582 } | 647 } |
| 583 | 648 |
| 584 | 649 |
| 585 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name) { | 650 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name) { |
| 586 #ifdef ENABLE_LOGGING_AND_PROFILING | 651 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 587 if (logfile_ == NULL || !FLAG_log_code) return; | 652 if (logfile_ == NULL || !FLAG_log_code) return; |
| 588 ScopedLock sl(mutex_); | 653 LogMessageBuilder msg; |
| 589 SmartPointer<char> str = | 654 SmartPointer<char> str = |
| 590 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 655 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 591 fprintf(logfile_, "code-creation,%s,0x%x,%d,\"%s\"\n", tag, | 656 msg.Append("code-creation,%s,0x%x,%d,\"%s\"\n", tag, |
| 592 reinterpret_cast<unsigned int>(code->address()), | 657 reinterpret_cast<unsigned int>(code->address()), |
| 593 code->instruction_size(), *str); | 658 code->instruction_size(), *str); |
| 659 msg.WriteToLogFile(); |
| 594 #endif | 660 #endif |
| 595 } | 661 } |
| 596 | 662 |
| 597 | 663 |
| 598 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name, | 664 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name, |
| 599 String* source, int line) { | 665 String* source, int line) { |
| 600 #ifdef ENABLE_LOGGING_AND_PROFILING | 666 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 601 if (logfile_ == NULL || !FLAG_log_code) return; | 667 if (logfile_ == NULL || !FLAG_log_code) return; |
| 602 ScopedLock sl(mutex_); | 668 LogMessageBuilder msg; |
| 603 SmartPointer<char> str = | 669 SmartPointer<char> str = |
| 604 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 670 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 605 SmartPointer<char> sourcestr = | 671 SmartPointer<char> sourcestr = |
| 606 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 672 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 607 fprintf(logfile_, "code-creation,%s,0x%x,%d,\"%s %s:%d\"\n", tag, | 673 msg.Append("code-creation,%s,0x%x,%d,\"%s %s:%d\"\n", tag, |
| 608 reinterpret_cast<unsigned int>(code->address()), | 674 reinterpret_cast<unsigned int>(code->address()), |
| 609 code->instruction_size(), *str, *sourcestr, line); | 675 code->instruction_size(), *str, *sourcestr, line); |
| 676 msg.WriteToLogFile(); |
| 610 #endif | 677 #endif |
| 611 } | 678 } |
| 612 | 679 |
| 613 | 680 |
| 614 void Logger::CodeCreateEvent(const char* tag, Code* code, int args_count) { | 681 void Logger::CodeCreateEvent(const char* tag, Code* code, int args_count) { |
| 615 #ifdef ENABLE_LOGGING_AND_PROFILING | 682 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 616 if (logfile_ == NULL || !FLAG_log_code) return; | 683 if (logfile_ == NULL || !FLAG_log_code) return; |
| 617 ScopedLock sl(mutex_); | 684 LogMessageBuilder msg; |
| 618 | 685 msg.Append("code-creation,%s,0x%x,%d,\"args_count: %d\"\n", tag, |
| 619 fprintf(logfile_, "code-creation,%s,0x%x,%d,\"args_count: %d\"\n", tag, | 686 reinterpret_cast<unsigned int>(code->address()), |
| 620 reinterpret_cast<unsigned int>(code->address()), | 687 code->instruction_size(), |
| 621 code->instruction_size(), | 688 args_count); |
| 622 args_count); | 689 msg.WriteToLogFile(); |
| 623 #endif | 690 #endif |
| 624 } | 691 } |
| 625 | 692 |
| 626 | 693 |
| 627 void Logger::CodeAllocateEvent(Code* code, Assembler* assem) { | 694 void Logger::CodeAllocateEvent(Code* code, Assembler* assem) { |
| 628 #ifdef ENABLE_LOGGING_AND_PROFILING | 695 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 629 if (logfile_ == NULL || !FLAG_log_code) return; | 696 if (logfile_ == NULL || !FLAG_log_code) return; |
| 630 ScopedLock sl(mutex_); | 697 LogMessageBuilder msg; |
| 631 | 698 msg.Append("code-allocate,0x%x,0x%x\n", |
| 632 fprintf(logfile_, "code-allocate,0x%x,0x%x\n", | 699 reinterpret_cast<unsigned int>(code->address()), |
| 633 reinterpret_cast<unsigned int>(code->address()), | 700 reinterpret_cast<unsigned int>(assem)); |
| 634 reinterpret_cast<unsigned int>(assem)); | 701 msg.WriteToLogFile(); |
| 635 #endif | 702 #endif |
| 636 } | 703 } |
| 637 | 704 |
| 638 | 705 |
| 639 void Logger::CodeMoveEvent(Address from, Address to) { | 706 void Logger::CodeMoveEvent(Address from, Address to) { |
| 640 #ifdef ENABLE_LOGGING_AND_PROFILING | 707 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 641 if (logfile_ == NULL || !FLAG_log_code) return; | 708 if (logfile_ == NULL || !FLAG_log_code) return; |
| 642 ScopedLock sl(mutex_); | 709 LogMessageBuilder msg; |
| 643 fprintf(logfile_, "code-move,0x%x,0x%x\n", | 710 msg.Append("code-move,0x%x,0x%x\n", |
| 644 reinterpret_cast<unsigned int>(from), | 711 reinterpret_cast<unsigned int>(from), |
| 645 reinterpret_cast<unsigned int>(to)); | 712 reinterpret_cast<unsigned int>(to)); |
| 713 msg.WriteToLogFile(); |
| 646 #endif | 714 #endif |
| 647 } | 715 } |
| 648 | 716 |
| 649 | 717 |
| 650 void Logger::CodeDeleteEvent(Address from) { | 718 void Logger::CodeDeleteEvent(Address from) { |
| 651 #ifdef ENABLE_LOGGING_AND_PROFILING | 719 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 652 if (logfile_ == NULL || !FLAG_log_code) return; | 720 if (logfile_ == NULL || !FLAG_log_code) return; |
| 653 ScopedLock sl(mutex_); | 721 LogMessageBuilder msg; |
| 654 fprintf(logfile_, "code-delete,0x%x\n", reinterpret_cast<unsigned int>(from)); | 722 msg.Append("code-delete,0x%x\n", reinterpret_cast<unsigned int>(from)); |
| 723 msg.WriteToLogFile(); |
| 655 #endif | 724 #endif |
| 656 } | 725 } |
| 657 | 726 |
| 658 | 727 |
| 659 void Logger::BeginCodeRegionEvent(CodeRegion* region, | 728 void Logger::BeginCodeRegionEvent(CodeRegion* region, |
| 660 Assembler* masm, | 729 Assembler* masm, |
| 661 const char* name) { | 730 const char* name) { |
| 662 #ifdef ENABLE_LOGGING_AND_PROFILING | 731 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 663 if (logfile_ == NULL || !FLAG_log_code) return; | 732 if (logfile_ == NULL || !FLAG_log_code) return; |
| 664 ScopedLock sl(mutex_); | 733 LogMessageBuilder msg; |
| 665 fprintf(logfile_, "begin-code-region,0x%x,0x%x,0x%x,%s\n", | 734 msg.Append("begin-code-region,0x%x,0x%x,0x%x,%s\n", |
| 666 reinterpret_cast<unsigned int>(region), | 735 reinterpret_cast<unsigned int>(region), |
| 667 reinterpret_cast<unsigned int>(masm), | 736 reinterpret_cast<unsigned int>(masm), |
| 668 masm->pc_offset(), | 737 masm->pc_offset(), |
| 669 name); | 738 name); |
| 739 msg.WriteToLogFile(); |
| 670 #endif | 740 #endif |
| 671 } | 741 } |
| 672 | 742 |
| 673 | 743 |
| 674 void Logger::EndCodeRegionEvent(CodeRegion* region, Assembler* masm) { | 744 void Logger::EndCodeRegionEvent(CodeRegion* region, Assembler* masm) { |
| 675 #ifdef ENABLE_LOGGING_AND_PROFILING | 745 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 676 if (logfile_ == NULL || !FLAG_log_code) return; | 746 if (logfile_ == NULL || !FLAG_log_code) return; |
| 677 ScopedLock sl(mutex_); | 747 LogMessageBuilder msg; |
| 678 fprintf(logfile_, "end-code-region,0x%x,0x%x,0x%x\n", | 748 msg.Append("end-code-region,0x%x,0x%x,0x%x\n", |
| 679 reinterpret_cast<unsigned int>(region), | 749 reinterpret_cast<unsigned int>(region), |
| 680 reinterpret_cast<unsigned int>(masm), | 750 reinterpret_cast<unsigned int>(masm), |
| 681 masm->pc_offset()); | 751 masm->pc_offset()); |
| 752 msg.WriteToLogFile(); |
| 682 #endif | 753 #endif |
| 683 } | 754 } |
| 684 | 755 |
| 685 | 756 |
| 686 void Logger::ResourceEvent(const char* name, const char* tag) { | 757 void Logger::ResourceEvent(const char* name, const char* tag) { |
| 687 #ifdef ENABLE_LOGGING_AND_PROFILING | 758 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 688 if (logfile_ == NULL || !FLAG_log) return; | 759 if (logfile_ == NULL || !FLAG_log) return; |
| 689 ScopedLock sl(mutex_); | 760 ScopedLock sl(mutex_); |
| 690 fprintf(logfile_, "%s,%s,", name, tag); | 761 fprintf(logfile_, "%s,%s,", name, tag); |
| 691 | 762 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 } | 924 } |
| 854 } else { | 925 } else { |
| 855 stream.Put(*p); | 926 stream.Put(*p); |
| 856 } | 927 } |
| 857 } | 928 } |
| 858 SmartPointer<const char> expanded = stream.ToCString(); | 929 SmartPointer<const char> expanded = stream.ToCString(); |
| 859 logfile_ = OS::FOpen(*expanded, "w"); | 930 logfile_ = OS::FOpen(*expanded, "w"); |
| 860 } else { | 931 } else { |
| 861 logfile_ = OS::FOpen(FLAG_logfile, "w"); | 932 logfile_ = OS::FOpen(FLAG_logfile, "w"); |
| 862 } | 933 } |
| 934 message_buffer_ = NewArray<char>(kMessageBufferSize); |
| 863 mutex_ = OS::CreateMutex(); | 935 mutex_ = OS::CreateMutex(); |
| 864 } | 936 } |
| 865 | 937 |
| 866 current_state_ = new VMState(OTHER); | 938 current_state_ = new VMState(OTHER); |
| 867 | 939 |
| 868 ticker_ = new Ticker(10); | 940 ticker_ = new Ticker(10); |
| 869 | 941 |
| 870 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { | 942 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { |
| 871 sliding_state_window_ = new SlidingStateWindow(); | 943 sliding_state_window_ = new SlidingStateWindow(); |
| 872 } | 944 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 899 while (current_state_) delete current_state_; | 971 while (current_state_) delete current_state_; |
| 900 delete sliding_state_window_; | 972 delete sliding_state_window_; |
| 901 | 973 |
| 902 delete ticker_; | 974 delete ticker_; |
| 903 | 975 |
| 904 if (logfile_ != NULL) { | 976 if (logfile_ != NULL) { |
| 905 fclose(logfile_); | 977 fclose(logfile_); |
| 906 logfile_ = NULL; | 978 logfile_ = NULL; |
| 907 delete mutex_; | 979 delete mutex_; |
| 908 mutex_ = NULL; | 980 mutex_ = NULL; |
| 981 DeleteArray(message_buffer_); |
| 909 } | 982 } |
| 910 #endif | 983 #endif |
| 911 } | 984 } |
| 912 | 985 |
| 913 | 986 |
| 914 void Logger::EnableSlidingStateWindow() { | 987 void Logger::EnableSlidingStateWindow() { |
| 915 #ifdef ENABLE_LOGGING_AND_PROFILING | 988 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 916 // If the ticker is NULL, Logger::Setup has not been called yet. In | 989 // If the ticker is NULL, Logger::Setup has not been called yet. In |
| 917 // that case, we set the sliding_state_window flag so that the | 990 // that case, we set the sliding_state_window flag so that the |
| 918 // sliding window computation will be started when Logger::Setup is | 991 // sliding window computation will be started when Logger::Setup is |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 if (FLAG_log_state_changes) { | 1045 if (FLAG_log_state_changes) { |
| 973 LOG(UncheckedStringEvent("Leaving", StateToString(state_))); | 1046 LOG(UncheckedStringEvent("Leaving", StateToString(state_))); |
| 974 if (previous_) { | 1047 if (previous_) { |
| 975 LOG(UncheckedStringEvent("To", StateToString(previous_->state_))); | 1048 LOG(UncheckedStringEvent("To", StateToString(previous_->state_))); |
| 976 } | 1049 } |
| 977 } | 1050 } |
| 978 } | 1051 } |
| 979 #endif | 1052 #endif |
| 980 | 1053 |
| 981 } } // namespace v8::internal | 1054 } } // namespace v8::internal |
| OLD | NEW |