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 |