Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 TickSample sample; | 327 TickSample sample; |
| 328 bool overflow = Remove(&sample); | 328 bool overflow = Remove(&sample); |
| 329 i::Isolate* isolate = ISOLATE; | 329 i::Isolate* isolate = ISOLATE; |
| 330 while (running_) { | 330 while (running_) { |
| 331 LOG(isolate, TickEvent(&sample, overflow)); | 331 LOG(isolate, TickEvent(&sample, overflow)); |
| 332 overflow = Remove(&sample); | 332 overflow = Remove(&sample); |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 | 335 |
| 336 | 336 |
| 337 // Low-level profiling event structures. | |
| 338 | |
| 339 struct LowLevelCodeCreateStruct { | |
| 340 static const char kTag = 'C'; | |
| 341 | |
| 342 int32_t name_size; | |
| 343 Address code_address; | |
| 344 int32_t code_size; | |
| 345 }; | |
| 346 | |
| 347 | |
| 348 struct LowLevelCodeMoveStruct { | |
| 349 static const char kTag = 'M'; | |
| 350 | |
| 351 Address from_address; | |
| 352 Address to_address; | |
| 353 }; | |
| 354 | |
| 355 | |
| 356 struct LowLevelCodeDeleteStruct { | |
| 357 static const char kTag = 'D'; | |
| 358 | |
| 359 Address address; | |
| 360 }; | |
| 361 | |
| 362 | |
| 363 struct LowLevelSnapshotPositionStruct { | |
| 364 static const char kTag = 'P'; | |
| 365 | |
| 366 Address address; | |
| 367 int32_t position; | |
| 368 }; | |
| 369 | |
| 370 | |
| 371 static const char kCodeMovingGCTag = 'G'; | |
| 372 | |
| 373 | |
| 337 // | 374 // |
| 338 // Logger class implementation. | 375 // Logger class implementation. |
| 339 // | 376 // |
| 340 | 377 |
| 378 class Logger::NameBuffer { | |
| 379 public: | |
| 380 NameBuffer() { Reset(); } | |
| 381 | |
| 382 void Reset() { | |
| 383 utf8_pos_ = 0; | |
| 384 } | |
| 385 | |
| 386 void AppendString(String* str) { | |
| 387 if (str == NULL) return; | |
| 388 if (str->HasOnlyAsciiChars()) { | |
| 389 int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_); | |
| 390 String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length); | |
| 391 utf8_pos_ += utf8_length; | |
| 392 return; | |
| 393 } | |
| 394 int uc16_length = Min(str->length(), kUc16BufferSize); | |
| 395 String::WriteToFlat(str, uc16_buffer_, 0, uc16_length); | |
| 396 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
| 397 uc16 c = uc16_buffer_[i]; | |
| 398 if (c <= String::kMaxAsciiCharCodeU) { | |
| 399 utf8_buffer_[utf8_pos_++] = c; | |
| 400 } else { | |
| 401 int char_length = unibrow::Utf8::Length(c); | |
| 402 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
| 403 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c); | |
| 404 utf8_pos_ += char_length; | |
| 405 } | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 void AppendBytes(const char* bytes, int size) { | |
| 410 size = Min(size, kUtf8BufferSize - utf8_pos_); | |
| 411 memcpy(utf8_buffer_ + utf8_pos_, bytes, size); | |
| 412 utf8_pos_ += size; | |
| 413 } | |
| 414 | |
| 415 void AppendBytes(const char* bytes) { | |
| 416 AppendBytes(bytes, StrLength(bytes)); | |
| 417 } | |
| 418 | |
| 419 void AppendByte(char c) { | |
| 420 if (utf8_pos_ >= kUtf8BufferSize) return; | |
| 421 utf8_buffer_[utf8_pos_++] = c; | |
| 422 } | |
| 423 | |
| 424 void AppendInt(int n) { | |
| 425 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); | |
| 426 int size = OS::SNPrintF(buffer, "%d", n); | |
| 427 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 428 utf8_pos_ += size; | |
| 429 } | |
| 430 } | |
| 431 | |
| 432 const char* get() { return utf8_buffer_; } | |
| 433 int size() const { return utf8_pos_; } | |
| 434 | |
| 435 private: | |
| 436 static const int kUtf8BufferSize = 512; | |
| 437 static const int kUc16BufferSize = 128; | |
| 438 | |
| 439 int utf8_pos_; | |
| 440 char utf8_buffer_[kUtf8BufferSize]; | |
| 441 uc16 uc16_buffer_[kUc16BufferSize]; | |
| 442 }; | |
| 443 | |
| 444 | |
| 445 static bool PointerEquals(void* lhs, void* rhs) { | |
| 446 return lhs == rhs; | |
| 447 } | |
| 448 | |
| 449 | |
| 341 Logger::Logger() | 450 Logger::Logger() |
| 342 : ticker_(NULL), | 451 : ticker_(NULL), |
| 343 profiler_(NULL), | 452 profiler_(NULL), |
| 344 sliding_state_window_(NULL), | 453 sliding_state_window_(NULL), |
| 345 log_events_(NULL), | 454 log_events_(NULL), |
| 346 logging_nesting_(0), | 455 logging_nesting_(0), |
| 347 cpu_profiler_nesting_(0), | 456 cpu_profiler_nesting_(0), |
| 348 heap_profiler_nesting_(0), | 457 heap_profiler_nesting_(0), |
| 349 log_(new Log(this)), | 458 log_(new Log(this)), |
| 459 name_buffer_(new NameBuffer), | |
| 460 address_to_name_map_(NULL), | |
| 350 is_initialized_(false), | 461 is_initialized_(false), |
| 351 last_address_(NULL), | 462 last_address_(NULL), |
| 352 prev_sp_(NULL), | 463 prev_sp_(NULL), |
| 353 prev_function_(NULL), | 464 prev_function_(NULL), |
| 354 prev_to_(NULL), | 465 prev_to_(NULL), |
| 355 prev_code_(NULL) { | 466 prev_code_(NULL) { |
| 356 } | 467 } |
| 357 | 468 |
| 469 | |
| 358 Logger::~Logger() { | 470 Logger::~Logger() { |
| 471 if (address_to_name_map_ != NULL) { | |
| 472 for (HashMap::Entry* p = address_to_name_map_->Start(); | |
| 473 p != NULL; | |
| 474 p = address_to_name_map_->Next(p)) { | |
| 475 DeleteArray(static_cast<const char*>(p->value)); | |
| 476 } | |
| 477 delete address_to_name_map_; | |
| 478 } | |
| 479 delete name_buffer_; | |
| 359 delete log_; | 480 delete log_; |
| 360 } | 481 } |
| 361 | 482 |
| 483 | |
| 362 #define DECLARE_EVENT(ignore1, name) name, | 484 #define DECLARE_EVENT(ignore1, name) name, |
| 363 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 485 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| 364 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | 486 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) |
| 365 }; | 487 }; |
| 366 #undef DECLARE_EVENT | 488 #undef DECLARE_EVENT |
| 367 | 489 |
| 368 | 490 |
| 369 void Logger::ProfilerBeginEvent() { | 491 void Logger::ProfilerBeginEvent() { |
| 370 if (!log_->IsEnabled()) return; | 492 if (!log_->IsEnabled()) return; |
| 371 LogMessageBuilder msg(this); | 493 LogMessageBuilder msg(this); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 728 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 850 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 729 CallbackEventInternal("set ", *str, entry_point); | 851 CallbackEventInternal("set ", *str, entry_point); |
| 730 #endif | 852 #endif |
| 731 } | 853 } |
| 732 | 854 |
| 733 | 855 |
| 734 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 856 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 735 Code* code, | 857 Code* code, |
| 736 const char* comment) { | 858 const char* comment) { |
| 737 #ifdef ENABLE_LOGGING_AND_PROFILING | 859 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 738 if (!log_->IsEnabled() || !FLAG_log_code) return; | 860 if (!log_->IsEnabled()) return; |
| 861 if (FLAG_ll_prof || Serializer::enabled()) { | |
| 862 name_buffer_->Reset(); | |
| 863 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 864 name_buffer_->AppendByte(':'); | |
| 865 name_buffer_->AppendBytes(comment); | |
| 866 } | |
| 867 if (FLAG_ll_prof) { | |
| 868 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 869 } | |
| 870 if (Serializer::enabled()) { | |
| 871 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 872 } | |
| 873 if (!FLAG_log_code) return; | |
| 739 LogMessageBuilder msg(this); | 874 LogMessageBuilder msg(this); |
| 740 msg.Append("%s,%s,", | 875 msg.Append("%s,%s,", |
| 741 kLogEventsNames[CODE_CREATION_EVENT], | 876 kLogEventsNames[CODE_CREATION_EVENT], |
| 742 kLogEventsNames[tag]); | 877 kLogEventsNames[tag]); |
| 743 msg.AppendAddress(code->address()); | 878 msg.AppendAddress(code->address()); |
| 744 msg.Append(",%d,\"", code->ExecutableSize()); | 879 msg.Append(",%d,\"", code->ExecutableSize()); |
| 745 for (const char* p = comment; *p != '\0'; p++) { | 880 for (const char* p = comment; *p != '\0'; p++) { |
| 746 if (*p == '"') { | 881 if (*p == '"') { |
| 747 msg.Append('\\'); | 882 msg.Append('\\'); |
| 748 } | 883 } |
| 749 msg.Append(*p); | 884 msg.Append(*p); |
| 750 } | 885 } |
| 751 msg.Append('"'); | 886 msg.Append('"'); |
| 752 LowLevelCodeCreateEvent(code, &msg); | |
| 753 msg.Append('\n'); | 887 msg.Append('\n'); |
| 754 msg.WriteToLogFile(); | 888 msg.WriteToLogFile(); |
| 755 #endif | 889 #endif |
| 756 } | 890 } |
| 757 | 891 |
| 758 | 892 |
| 759 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 893 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 760 Code* code, | 894 Code* code, |
| 761 String* name) { | 895 String* name) { |
| 762 #ifdef ENABLE_LOGGING_AND_PROFILING | 896 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 763 if (name != NULL) { | 897 if (!log_->IsEnabled()) return; |
| 764 SmartPointer<char> str = | 898 if (FLAG_ll_prof || Serializer::enabled()) { |
| 765 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 899 name_buffer_->Reset(); |
| 766 CodeCreateEvent(tag, code, *str); | 900 name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| 767 } else { | 901 name_buffer_->AppendByte(':'); |
| 768 CodeCreateEvent(tag, code, ""); | 902 name_buffer_->AppendString(name); |
| 769 } | 903 } |
| 904 if (FLAG_ll_prof) { | |
| 905 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 906 } | |
| 907 if (Serializer::enabled()) { | |
| 908 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 909 } | |
| 910 if (!FLAG_log_code) return; | |
| 911 LogMessageBuilder msg(this); | |
| 912 msg.Append("%s,%s,", | |
| 913 kLogEventsNames[CODE_CREATION_EVENT], | |
| 914 kLogEventsNames[tag]); | |
| 915 msg.AppendAddress(code->address()); | |
| 916 msg.Append(",%d,\"", code->ExecutableSize()); | |
| 917 msg.AppendDetailed(name, false); | |
| 918 msg.Append('"'); | |
| 919 msg.Append('\n'); | |
| 920 msg.WriteToLogFile(); | |
| 770 #endif | 921 #endif |
| 771 } | 922 } |
| 772 | 923 |
| 773 | 924 |
| 774 #ifdef ENABLE_LOGGING_AND_PROFILING | 925 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 775 // ComputeMarker must only be used when SharedFunctionInfo is known. | 926 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 776 static const char* ComputeMarker(Code* code) { | 927 static const char* ComputeMarker(Code* code) { |
| 777 switch (code->kind()) { | 928 switch (code->kind()) { |
| 778 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | 929 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 779 case Code::OPTIMIZED_FUNCTION: return "*"; | 930 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 780 default: return ""; | 931 default: return ""; |
| 781 } | 932 } |
| 782 } | 933 } |
| 783 #endif | 934 #endif |
| 784 | 935 |
| 785 | 936 |
| 786 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 937 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 787 Code* code, | 938 Code* code, |
| 788 SharedFunctionInfo* shared, | 939 SharedFunctionInfo* shared, |
| 789 String* name) { | 940 String* name) { |
| 790 #ifdef ENABLE_LOGGING_AND_PROFILING | 941 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 791 if (!log_->IsEnabled() || !FLAG_log_code) return; | 942 if (!log_->IsEnabled()) return; |
| 943 if (FLAG_ll_prof || Serializer::enabled()) { | |
| 944 name_buffer_->Reset(); | |
| 945 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 946 name_buffer_->AppendByte(':'); | |
| 947 name_buffer_->AppendString(name); | |
| 948 } | |
| 949 if (FLAG_ll_prof) { | |
| 950 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 951 } | |
| 952 if (Serializer::enabled()) { | |
| 953 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 954 } | |
| 955 if (!FLAG_log_code) return; | |
| 792 if (code == Isolate::Current()->builtins()->builtin( | 956 if (code == Isolate::Current()->builtins()->builtin( |
| 793 Builtins::kLazyCompile)) | 957 Builtins::kLazyCompile)) |
| 794 return; | 958 return; |
| 795 | 959 |
| 796 LogMessageBuilder msg(this); | 960 LogMessageBuilder msg(this); |
| 797 SmartPointer<char> str = | 961 SmartPointer<char> str = |
| 798 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 962 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 799 msg.Append("%s,%s,", | 963 msg.Append("%s,%s,", |
| 800 kLogEventsNames[CODE_CREATION_EVENT], | 964 kLogEventsNames[CODE_CREATION_EVENT], |
| 801 kLogEventsNames[tag]); | 965 kLogEventsNames[tag]); |
| 802 msg.AppendAddress(code->address()); | 966 msg.AppendAddress(code->address()); |
| 803 msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); | 967 msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); |
| 804 msg.AppendAddress(shared->address()); | 968 msg.AppendAddress(shared->address()); |
| 805 msg.Append(",%s", ComputeMarker(code)); | 969 msg.Append(",%s", ComputeMarker(code)); |
| 806 LowLevelCodeCreateEvent(code, &msg); | |
| 807 msg.Append('\n'); | 970 msg.Append('\n'); |
| 808 msg.WriteToLogFile(); | 971 msg.WriteToLogFile(); |
| 809 #endif | 972 #endif |
| 810 } | 973 } |
| 811 | 974 |
| 812 | 975 |
| 813 // Although, it is possible to extract source and line from | 976 // Although, it is possible to extract source and line from |
| 814 // the SharedFunctionInfo object, we left it to caller | 977 // the SharedFunctionInfo object, we left it to caller |
| 815 // to leave logging functions free from heap allocations. | 978 // to leave logging functions free from heap allocations. |
| 816 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 979 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 817 Code* code, | 980 Code* code, |
| 818 SharedFunctionInfo* shared, | 981 SharedFunctionInfo* shared, |
| 819 String* source, int line) { | 982 String* source, int line) { |
| 820 #ifdef ENABLE_LOGGING_AND_PROFILING | 983 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 821 if (!log_->IsEnabled() || !FLAG_log_code) return; | 984 if (!log_->IsEnabled()) return; |
| 985 if (FLAG_ll_prof || Serializer::enabled()) { | |
| 986 name_buffer_->Reset(); | |
| 987 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 988 name_buffer_->AppendByte(':'); | |
| 989 name_buffer_->AppendString(shared->DebugName()); | |
| 990 name_buffer_->AppendByte(' '); | |
| 991 name_buffer_->AppendString(source); | |
| 992 name_buffer_->AppendByte(':'); | |
| 993 name_buffer_->AppendInt(line); | |
| 994 } | |
| 995 if (FLAG_ll_prof) { | |
| 996 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 997 } | |
| 998 if (Serializer::enabled()) { | |
| 999 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 1000 } | |
| 1001 if (!FLAG_log_code) return; | |
| 822 LogMessageBuilder msg(this); | 1002 LogMessageBuilder msg(this); |
| 823 SmartPointer<char> name = | 1003 SmartPointer<char> name = |
| 824 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1004 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 825 SmartPointer<char> sourcestr = | 1005 SmartPointer<char> sourcestr = |
| 826 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1006 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 827 msg.Append("%s,%s,", | 1007 msg.Append("%s,%s,", |
| 828 kLogEventsNames[CODE_CREATION_EVENT], | 1008 kLogEventsNames[CODE_CREATION_EVENT], |
| 829 kLogEventsNames[tag]); | 1009 kLogEventsNames[tag]); |
| 830 msg.AppendAddress(code->address()); | 1010 msg.AppendAddress(code->address()); |
| 831 msg.Append(",%d,\"%s %s:%d\",", | 1011 msg.Append(",%d,\"%s %s:%d\",", |
| 832 code->ExecutableSize(), | 1012 code->ExecutableSize(), |
| 833 *name, | 1013 *name, |
| 834 *sourcestr, | 1014 *sourcestr, |
| 835 line); | 1015 line); |
| 836 msg.AppendAddress(shared->address()); | 1016 msg.AppendAddress(shared->address()); |
| 837 msg.Append(",%s", ComputeMarker(code)); | 1017 msg.Append(",%s", ComputeMarker(code)); |
| 838 LowLevelCodeCreateEvent(code, &msg); | |
| 839 msg.Append('\n'); | 1018 msg.Append('\n'); |
| 840 msg.WriteToLogFile(); | 1019 msg.WriteToLogFile(); |
| 841 #endif | 1020 #endif |
| 842 } | 1021 } |
| 843 | 1022 |
| 844 | 1023 |
| 845 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { | 1024 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { |
| 846 #ifdef ENABLE_LOGGING_AND_PROFILING | 1025 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 847 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1026 if (!log_->IsEnabled()) return; |
| 1027 if (FLAG_ll_prof || Serializer::enabled()) { | |
| 1028 name_buffer_->Reset(); | |
| 1029 name_buffer_->AppendBytes(kLogEventsNames[tag]); | |
| 1030 name_buffer_->AppendByte(':'); | |
| 1031 name_buffer_->AppendInt(args_count); | |
| 1032 } | |
| 1033 if (FLAG_ll_prof) { | |
| 1034 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 1035 } | |
| 1036 if (Serializer::enabled()) { | |
| 1037 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 1038 } | |
| 1039 if (!FLAG_log_code) return; | |
| 848 LogMessageBuilder msg(this); | 1040 LogMessageBuilder msg(this); |
| 849 msg.Append("%s,%s,", | 1041 msg.Append("%s,%s,", |
| 850 kLogEventsNames[CODE_CREATION_EVENT], | 1042 kLogEventsNames[CODE_CREATION_EVENT], |
| 851 kLogEventsNames[tag]); | 1043 kLogEventsNames[tag]); |
| 852 msg.AppendAddress(code->address()); | 1044 msg.AppendAddress(code->address()); |
| 853 msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count); | 1045 msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count); |
| 854 LowLevelCodeCreateEvent(code, &msg); | |
| 855 msg.Append('\n'); | 1046 msg.Append('\n'); |
| 856 msg.WriteToLogFile(); | 1047 msg.WriteToLogFile(); |
| 857 #endif | 1048 #endif |
| 858 } | 1049 } |
| 859 | 1050 |
| 860 | 1051 |
| 861 void Logger::CodeMovingGCEvent() { | 1052 void Logger::CodeMovingGCEvent() { |
| 862 #ifdef ENABLE_LOGGING_AND_PROFILING | 1053 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 863 if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return; | 1054 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 864 LogMessageBuilder msg(this); | 1055 LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag)); |
| 865 msg.Append("%s\n", kLogEventsNames[CODE_MOVING_GC]); | |
| 866 msg.WriteToLogFile(); | |
| 867 OS::SignalCodeMovingGC(); | 1056 OS::SignalCodeMovingGC(); |
| 868 #endif | 1057 #endif |
| 869 } | 1058 } |
| 870 | 1059 |
| 871 | 1060 |
| 872 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1061 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 873 #ifdef ENABLE_LOGGING_AND_PROFILING | 1062 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 874 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1063 if (!log_->IsEnabled()) return; |
| 1064 if (FLAG_ll_prof || Serializer::enabled()) { | |
| 1065 name_buffer_->Reset(); | |
| 1066 name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]); | |
| 1067 name_buffer_->AppendByte(':'); | |
| 1068 name_buffer_->AppendString(source); | |
| 1069 } | |
| 1070 if (FLAG_ll_prof) { | |
| 1071 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 1072 } | |
| 1073 if (Serializer::enabled()) { | |
| 1074 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | |
| 1075 } | |
| 1076 if (!FLAG_log_code) return; | |
| 875 LogMessageBuilder msg(this); | 1077 LogMessageBuilder msg(this); |
| 876 msg.Append("%s,%s,", | 1078 msg.Append("%s,%s,", |
| 877 kLogEventsNames[CODE_CREATION_EVENT], | 1079 kLogEventsNames[CODE_CREATION_EVENT], |
| 878 kLogEventsNames[REG_EXP_TAG]); | 1080 kLogEventsNames[REG_EXP_TAG]); |
| 879 msg.AppendAddress(code->address()); | 1081 msg.AppendAddress(code->address()); |
| 880 msg.Append(",%d,\"", code->ExecutableSize()); | 1082 msg.Append(",%d,\"", code->ExecutableSize()); |
| 881 msg.AppendDetailed(source, false); | 1083 msg.AppendDetailed(source, false); |
| 882 msg.Append('\"'); | 1084 msg.Append('\"'); |
| 883 LowLevelCodeCreateEvent(code, &msg); | |
| 884 msg.Append('\n'); | 1085 msg.Append('\n'); |
| 885 msg.WriteToLogFile(); | 1086 msg.WriteToLogFile(); |
| 886 #endif | 1087 #endif |
| 887 } | 1088 } |
| 888 | 1089 |
| 889 | 1090 |
| 890 void Logger::CodeMoveEvent(Address from, Address to) { | 1091 void Logger::CodeMoveEvent(Address from, Address to) { |
| 891 #ifdef ENABLE_LOGGING_AND_PROFILING | 1092 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1093 if (!log_->IsEnabled()) return; | |
| 1094 if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to); | |
| 1095 if (Serializer::enabled() && address_to_name_map_ != NULL) { | |
| 1096 Address code_address = from + Code::kHeaderSize; | |
| 1097 uint32_t hash = ComputePointerHash(code_address); | |
| 1098 HashMap::Entry* entry = address_to_name_map_->Lookup( | |
|
mnaganov (inactive)
2011/04/29 14:20:28
This code is repeated several times. Worth extract
Vitaly Repeshko
2011/04/29 15:50:40
Created a class. It's +20 lines overall, but the c
| |
| 1099 code_address, hash, false); | |
| 1100 ASSERT(entry != NULL); | |
| 1101 void* value = entry->value; | |
| 1102 address_to_name_map_->Remove(code_address, hash); | |
| 1103 entry = address_to_name_map_->Lookup(code_address, hash, true); | |
| 1104 ASSERT(entry->value == NULL); | |
| 1105 entry->value = value; | |
| 1106 return; | |
| 1107 } | |
| 892 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1108 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| 893 #endif | 1109 #endif |
| 894 } | 1110 } |
| 895 | 1111 |
| 896 | 1112 |
| 897 void Logger::CodeDeleteEvent(Address from) { | 1113 void Logger::CodeDeleteEvent(Address from) { |
| 898 #ifdef ENABLE_LOGGING_AND_PROFILING | 1114 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1115 if (!log_->IsEnabled()) return; | |
| 1116 if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from); | |
| 1117 if (Serializer::enabled() && address_to_name_map_ != NULL) { | |
| 1118 Address code_address = from + Code::kHeaderSize; | |
| 1119 uint32_t hash = ComputePointerHash(code_address); | |
| 1120 HashMap::Entry* entry = address_to_name_map_->Lookup( | |
| 1121 code_address, hash, false); | |
| 1122 if (entry != NULL) { | |
| 1123 DeleteArray(static_cast<const char*>(entry->value)); | |
| 1124 } | |
| 1125 address_to_name_map_->Remove(code_address, hash); | |
| 1126 return; | |
| 1127 } | |
| 899 DeleteEventInternal(CODE_DELETE_EVENT, from); | 1128 DeleteEventInternal(CODE_DELETE_EVENT, from); |
| 900 #endif | 1129 #endif |
| 901 } | 1130 } |
| 902 | 1131 |
| 903 | 1132 |
| 904 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1133 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| 905 #ifdef ENABLE_LOGGING_AND_PROFILING | 1134 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 906 if (!log_->IsEnabled() || !FLAG_log_snapshot_positions) return; | 1135 if (!log_->IsEnabled()) return; |
| 1136 if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos); | |
| 1137 if (Serializer::enabled() && address_to_name_map_ != NULL) { | |
| 1138 Address code_address = addr + Code::kHeaderSize; | |
| 1139 HashMap::Entry* entry = address_to_name_map_->Lookup( | |
| 1140 code_address, ComputePointerHash(code_address), false); | |
| 1141 if (entry == NULL) return; // Not a code object. | |
| 1142 LogMessageBuilder msg(this); | |
| 1143 msg.Append("%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | |
| 1144 for (const char* p = static_cast<const char*>(entry->value); | |
| 1145 *p != '\0'; | |
| 1146 ++p) { | |
| 1147 if (*p == '"') msg.Append('\\'); | |
| 1148 msg.Append(*p); | |
| 1149 } | |
| 1150 msg.Append("\"\n"); | |
| 1151 msg.WriteToLogFile(); | |
| 1152 } | |
| 1153 if (!FLAG_log_snapshot_positions) return; | |
| 907 LogMessageBuilder msg(this); | 1154 LogMessageBuilder msg(this); |
| 908 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 1155 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| 909 msg.AppendAddress(addr); | 1156 msg.AppendAddress(addr); |
| 910 msg.Append(",%d", pos); | 1157 msg.Append(",%d", pos); |
| 911 msg.Append('\n'); | 1158 msg.Append('\n'); |
| 912 msg.WriteToLogFile(); | 1159 msg.WriteToLogFile(); |
| 913 #endif | 1160 #endif |
| 914 } | 1161 } |
| 915 | 1162 |
| 916 | 1163 |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1301 EnumerateOptimizedFunctionsVisitor visitor(sfis, | 1548 EnumerateOptimizedFunctionsVisitor visitor(sfis, |
| 1302 code_objects, | 1549 code_objects, |
| 1303 &compiled_funcs_count); | 1550 &compiled_funcs_count); |
| 1304 Deoptimizer::VisitAllOptimizedFunctions(&visitor); | 1551 Deoptimizer::VisitAllOptimizedFunctions(&visitor); |
| 1305 | 1552 |
| 1306 return compiled_funcs_count; | 1553 return compiled_funcs_count; |
| 1307 } | 1554 } |
| 1308 | 1555 |
| 1309 | 1556 |
| 1310 void Logger::LogCodeObject(Object* object) { | 1557 void Logger::LogCodeObject(Object* object) { |
| 1311 if (FLAG_log_code) { | 1558 if (FLAG_log_code || FLAG_ll_prof) { |
| 1312 Code* code_object = Code::cast(object); | 1559 Code* code_object = Code::cast(object); |
| 1313 LogEventsAndTags tag = Logger::STUB_TAG; | 1560 LogEventsAndTags tag = Logger::STUB_TAG; |
| 1314 const char* description = "Unknown code from the snapshot"; | 1561 const char* description = "Unknown code from the snapshot"; |
| 1315 switch (code_object->kind()) { | 1562 switch (code_object->kind()) { |
| 1316 case Code::FUNCTION: | 1563 case Code::FUNCTION: |
| 1317 case Code::OPTIMIZED_FUNCTION: | 1564 case Code::OPTIMIZED_FUNCTION: |
| 1318 return; // We log this later using LogCompiledFunctions. | 1565 return; // We log this later using LogCompiledFunctions. |
| 1319 case Code::TYPE_RECORDING_BINARY_OP_IC: // fall through | 1566 case Code::TYPE_RECORDING_BINARY_OP_IC: // fall through |
| 1320 case Code::COMPARE_IC: // fall through | 1567 case Code::COMPARE_IC: // fall through |
| 1321 case Code::STUB: | 1568 case Code::STUB: |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1362 tag = Logger::KEYED_CALL_IC_TAG; | 1609 tag = Logger::KEYED_CALL_IC_TAG; |
| 1363 break; | 1610 break; |
| 1364 } | 1611 } |
| 1365 PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description)); | 1612 PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description)); |
| 1366 } | 1613 } |
| 1367 } | 1614 } |
| 1368 | 1615 |
| 1369 | 1616 |
| 1370 void Logger::LogCodeInfo() { | 1617 void Logger::LogCodeInfo() { |
| 1371 #ifdef ENABLE_LOGGING_AND_PROFILING | 1618 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1372 if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return; | 1619 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1373 #if V8_TARGET_ARCH_IA32 | 1620 #if V8_TARGET_ARCH_IA32 |
| 1374 const char arch[] = "ia32"; | 1621 const char arch[] = "ia32"; |
| 1375 #elif V8_TARGET_ARCH_X64 | 1622 #elif V8_TARGET_ARCH_X64 |
| 1376 const char arch[] = "x64"; | 1623 const char arch[] = "x64"; |
| 1377 #elif V8_TARGET_ARCH_ARM | 1624 #elif V8_TARGET_ARCH_ARM |
| 1378 const char arch[] = "arm"; | 1625 const char arch[] = "arm"; |
| 1379 #else | 1626 #else |
| 1380 const char arch[] = "unknown"; | 1627 const char arch[] = "unknown"; |
| 1381 #endif | 1628 #endif |
| 1382 LogMessageBuilder msg(this); | 1629 LowLevelLogWriteBytes(arch, sizeof(arch)); |
| 1383 msg.Append("code-info,%s,%d\n", arch, Code::kHeaderSize); | |
| 1384 msg.WriteToLogFile(); | |
| 1385 #endif // ENABLE_LOGGING_AND_PROFILING | 1630 #endif // ENABLE_LOGGING_AND_PROFILING |
| 1386 } | 1631 } |
| 1387 | 1632 |
| 1388 | 1633 |
| 1389 void Logger::LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg) { | 1634 static char* CopyName(const char* name, int name_size) { |
| 1390 if (!FLAG_ll_prof || log_->output_code_handle_ == NULL) return; | 1635 char* result = NewArray<char>(name_size + 1); |
| 1391 int pos = static_cast<int>(ftell(log_->output_code_handle_)); | 1636 for (int i = 0; i < name_size; ++i) { |
| 1392 size_t rv = fwrite(code->instruction_start(), 1, code->instruction_size(), | 1637 char c = name[i]; |
| 1393 log_->output_code_handle_); | 1638 if (c == '\0') c = ' '; |
| 1394 ASSERT(static_cast<size_t>(code->instruction_size()) == rv); | 1639 result[i] = c; |
| 1395 USE(rv); | 1640 } |
| 1396 msg->Append(",%d", pos); | 1641 result[name_size] = '\0'; |
| 1642 return result; | |
| 1397 } | 1643 } |
| 1398 | 1644 |
| 1399 | 1645 |
| 1646 void Logger::RegisterSnapshotCodeName(Code* code, | |
| 1647 const char* name, | |
| 1648 int name_size) { | |
| 1649 ASSERT(Serializer::enabled()); | |
| 1650 if (address_to_name_map_ == NULL) { | |
| 1651 address_to_name_map_ = new HashMap(&PointerEquals); | |
| 1652 } | |
| 1653 Address code_address = code->instruction_start(); | |
| 1654 HashMap::Entry* entry = address_to_name_map_->Lookup( | |
| 1655 code_address, ComputePointerHash(code_address), true); | |
| 1656 if (entry->value == NULL) { | |
| 1657 entry->value = CopyName(name, name_size); | |
| 1658 } | |
| 1659 } | |
| 1660 | |
| 1661 | |
| 1662 void Logger::LowLevelCodeCreateEvent(Code* code, | |
| 1663 const char* name, | |
| 1664 int name_size) { | |
| 1665 if (log_->ll_output_handle_ == NULL) return; | |
| 1666 LowLevelCodeCreateStruct event; | |
| 1667 event.name_size = name_size; | |
| 1668 event.code_address = code->instruction_start(); | |
| 1669 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | |
| 1670 event.code_size = code->instruction_size(); | |
| 1671 LowLevelLogWriteStruct(event); | |
| 1672 LowLevelLogWriteBytes(name, name_size); | |
| 1673 LowLevelLogWriteBytes( | |
| 1674 reinterpret_cast<const char*>(code->instruction_start()), | |
| 1675 code->instruction_size()); | |
| 1676 } | |
| 1677 | |
| 1678 | |
| 1679 void Logger::LowLevelCodeMoveEvent(Address from, Address to) { | |
| 1680 if (log_->ll_output_handle_ == NULL) return; | |
| 1681 LowLevelCodeMoveStruct event; | |
| 1682 event.from_address = from + Code::kHeaderSize; | |
| 1683 event.to_address = to + Code::kHeaderSize; | |
| 1684 LowLevelLogWriteStruct(event); | |
| 1685 } | |
| 1686 | |
| 1687 | |
| 1688 void Logger::LowLevelCodeDeleteEvent(Address from) { | |
| 1689 if (log_->ll_output_handle_ == NULL) return; | |
| 1690 LowLevelCodeDeleteStruct event; | |
| 1691 event.address = from + Code::kHeaderSize; | |
| 1692 LowLevelLogWriteStruct(event); | |
| 1693 } | |
| 1694 | |
| 1695 | |
| 1696 void Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) { | |
| 1697 if (log_->ll_output_handle_ == NULL) return; | |
| 1698 LowLevelSnapshotPositionStruct event; | |
| 1699 event.address = addr + Code::kHeaderSize; | |
| 1700 event.position = pos; | |
| 1701 LowLevelLogWriteStruct(event); | |
| 1702 } | |
| 1703 | |
| 1704 | |
| 1705 void Logger::LowLevelLogWriteBytes(const char* bytes, int size) { | |
| 1706 size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_); | |
| 1707 ASSERT(static_cast<size_t>(size) == rv); | |
| 1708 USE(rv); | |
| 1709 } | |
| 1710 | |
| 1711 | |
| 1400 void Logger::LogCodeObjects() { | 1712 void Logger::LogCodeObjects() { |
| 1401 AssertNoAllocation no_alloc; | 1713 AssertNoAllocation no_alloc; |
| 1402 HeapIterator iterator; | 1714 HeapIterator iterator; |
| 1403 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1715 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1404 if (obj->IsCode()) LogCodeObject(obj); | 1716 if (obj->IsCode()) LogCodeObject(obj); |
| 1405 } | 1717 } |
| 1406 } | 1718 } |
| 1407 | 1719 |
| 1408 | 1720 |
| 1409 void Logger::LogCompiledFunctions() { | 1721 void Logger::LogCompiledFunctions() { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1489 | 1801 |
| 1490 | 1802 |
| 1491 bool Logger::Setup() { | 1803 bool Logger::Setup() { |
| 1492 #ifdef ENABLE_LOGGING_AND_PROFILING | 1804 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1493 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. | 1805 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. |
| 1494 if (is_initialized_) return true; | 1806 if (is_initialized_) return true; |
| 1495 is_initialized_ = true; | 1807 is_initialized_ = true; |
| 1496 | 1808 |
| 1497 // --ll-prof implies --log-code and --log-snapshot-positions. | 1809 // --ll-prof implies --log-code and --log-snapshot-positions. |
| 1498 if (FLAG_ll_prof) { | 1810 if (FLAG_ll_prof) { |
| 1499 FLAG_log_code = true; | |
| 1500 FLAG_log_snapshot_positions = true; | 1811 FLAG_log_snapshot_positions = true; |
| 1501 } | 1812 } |
| 1502 | 1813 |
| 1503 // --prof_lazy controls --log-code, implies --noprof_auto. | 1814 // --prof_lazy controls --log-code, implies --noprof_auto. |
| 1504 if (FLAG_prof_lazy) { | 1815 if (FLAG_prof_lazy) { |
| 1505 FLAG_log_code = false; | 1816 FLAG_log_code = false; |
| 1506 FLAG_prof_auto = false; | 1817 FLAG_prof_auto = false; |
| 1507 } | 1818 } |
| 1508 | 1819 |
| 1509 // TODO(isolates): this assert introduces cyclic dependency (logger | 1820 // TODO(isolates): this assert introduces cyclic dependency (logger |
| 1510 // -> thread local top -> heap -> logger). | 1821 // -> thread local top -> heap -> logger). |
| 1511 // ASSERT(VMState::is_outermost_external()); | 1822 // ASSERT(VMState::is_outermost_external()); |
| 1512 | 1823 |
| 1513 log_->Initialize(); | 1824 log_->Initialize(); |
| 1514 | 1825 |
| 1515 if (FLAG_ll_prof) LogCodeInfo(); | 1826 if (FLAG_ll_prof) LogCodeInfo(); |
| 1516 | 1827 |
| 1517 ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs); | 1828 ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs); |
| 1518 | 1829 |
| 1519 Isolate* isolate = Isolate::Current(); | 1830 Isolate* isolate = Isolate::Current(); |
| 1520 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { | 1831 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { |
| 1521 sliding_state_window_ = new SlidingStateWindow(isolate); | 1832 sliding_state_window_ = new SlidingStateWindow(isolate); |
| 1522 } | 1833 } |
| 1523 | 1834 |
| 1524 bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api | 1835 bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api |
| 1525 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect | 1836 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect |
| 1526 || FLAG_log_regexp || FLAG_log_state_changes; | 1837 || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof; |
| 1527 | 1838 |
| 1528 if (start_logging) { | 1839 if (start_logging) { |
| 1529 logging_nesting_ = 1; | 1840 logging_nesting_ = 1; |
| 1530 } | 1841 } |
| 1531 | 1842 |
| 1532 if (FLAG_prof) { | 1843 if (FLAG_prof) { |
| 1533 profiler_ = new Profiler(isolate); | 1844 profiler_ = new Profiler(isolate); |
| 1534 if (!FLAG_prof_auto) { | 1845 if (!FLAG_prof_auto) { |
| 1535 profiler_->pause(); | 1846 profiler_->pause(); |
| 1536 } else { | 1847 } else { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1656 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { | 1967 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { |
| 1657 ASSERT(sampler->IsActive()); | 1968 ASSERT(sampler->IsActive()); |
| 1658 ScopedLock lock(mutex_); | 1969 ScopedLock lock(mutex_); |
| 1659 ASSERT(active_samplers_ != NULL); | 1970 ASSERT(active_samplers_ != NULL); |
| 1660 bool removed = active_samplers_->RemoveElement(sampler); | 1971 bool removed = active_samplers_->RemoveElement(sampler); |
| 1661 ASSERT(removed); | 1972 ASSERT(removed); |
| 1662 USE(removed); | 1973 USE(removed); |
| 1663 } | 1974 } |
| 1664 | 1975 |
| 1665 } } // namespace v8::internal | 1976 } } // namespace v8::internal |
| OLD | NEW |