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 |