| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 static bool paused_; | 140 static bool paused_; |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 bool Profiler::paused_ = false; | 143 bool Profiler::paused_ = false; |
| 144 | 144 |
| 145 | 145 |
| 146 // | 146 // |
| 147 // StackTracer implementation | 147 // StackTracer implementation |
| 148 // | 148 // |
| 149 void StackTracer::Trace(TickSample* sample) { | 149 void StackTracer::Trace(TickSample* sample) { |
| 150 sample->function = NULL; | 150 sample->tos = NULL; |
| 151 sample->frames_count = 0; | 151 sample->frames_count = 0; |
| 152 | 152 |
| 153 // Avoid collecting traces while doing GC. | 153 // Avoid collecting traces while doing GC. |
| 154 if (sample->state == GC) return; | 154 if (sample->state == GC) return; |
| 155 | 155 |
| 156 const Address js_entry_sp = Top::js_entry_sp(Top::GetCurrentThread()); | 156 const Address js_entry_sp = Top::js_entry_sp(Top::GetCurrentThread()); |
| 157 if (js_entry_sp == 0) { | 157 if (js_entry_sp == 0) { |
| 158 // Not executing JS now. | 158 // Not executing JS now. |
| 159 return; | 159 return; |
| 160 } | 160 } |
| 161 | 161 |
| 162 const Address function_address = | 162 // Sample potential return address value for frameless invocation of |
| 163 sample->fp + JavaScriptFrameConstants::kFunctionOffset; | 163 // stubs (we'll figure out later, if this value makes sense). |
| 164 if (SafeStackFrameIterator::IsWithinBounds(sample->sp, js_entry_sp, | 164 sample->tos = Memory::Address_at(sample->sp); |
| 165 function_address)) { | |
| 166 Object* object = Memory::Object_at(function_address); | |
| 167 if (object->IsHeapObject()) { | |
| 168 sample->function = HeapObject::cast(object)->address(); | |
| 169 } | |
| 170 } | |
| 171 | 165 |
| 172 int i = 0; | 166 int i = 0; |
| 173 const Address callback = Top::external_callback(); | 167 const Address callback = Top::external_callback(); |
| 174 // Surprisingly, PC can point _exactly_ to callback start, with good | 168 // Surprisingly, PC can point _exactly_ to callback start, with good |
| 175 // probability, and this will result in reporting fake nested | 169 // probability, and this will result in reporting fake nested |
| 176 // callback call. | 170 // callback call. |
| 177 if (callback != NULL && callback != sample->pc) { | 171 if (callback != NULL && callback != sample->pc) { |
| 178 sample->stack[i++] = callback; | 172 sample->stack[i++] = callback; |
| 179 } | 173 } |
| 180 | 174 |
| 181 SafeStackTraceFrameIterator it(sample->fp, sample->sp, | 175 SafeStackTraceFrameIterator it(sample->fp, sample->sp, |
| 182 sample->sp, js_entry_sp); | 176 sample->sp, js_entry_sp); |
| 183 while (!it.done() && i < TickSample::kMaxFramesCount) { | 177 while (!it.done() && i < TickSample::kMaxFramesCount) { |
| 184 Object* object = it.frame()->function_slot_object(); | 178 sample->stack[i++] = it.frame()->pc(); |
| 185 if (object->IsHeapObject()) { | |
| 186 sample->stack[i++] = HeapObject::cast(object)->address(); | |
| 187 } | |
| 188 it.Advance(); | 179 it.Advance(); |
| 189 } | 180 } |
| 190 sample->frames_count = i; | 181 sample->frames_count = i; |
| 191 } | 182 } |
| 192 | 183 |
| 193 | 184 |
| 194 // | 185 // |
| 195 // Ticker used to provide ticks to the profiler and the sliding state | 186 // Ticker used to provide ticks to the profiler and the sliding state |
| 196 // window. | 187 // window. |
| 197 // | 188 // |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 void Logger::SetterCallbackEvent(String* name, Address entry_point) { | 694 void Logger::SetterCallbackEvent(String* name, Address entry_point) { |
| 704 #ifdef ENABLE_LOGGING_AND_PROFILING | 695 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 705 if (!Log::IsEnabled() || !FLAG_log_code) return; | 696 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 706 SmartPointer<char> str = | 697 SmartPointer<char> str = |
| 707 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 698 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 708 CallbackEventInternal("set ", *str, entry_point); | 699 CallbackEventInternal("set ", *str, entry_point); |
| 709 #endif | 700 #endif |
| 710 } | 701 } |
| 711 | 702 |
| 712 | 703 |
| 713 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 714 static const char* ComputeMarker(Code* code) { | |
| 715 switch (code->kind()) { | |
| 716 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | |
| 717 case Code::OPTIMIZED_FUNCTION: return "*"; | |
| 718 default: return ""; | |
| 719 } | |
| 720 } | |
| 721 #endif | |
| 722 | |
| 723 | |
| 724 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 704 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 725 Code* code, | 705 Code* code, |
| 726 const char* comment) { | 706 const char* comment) { |
| 727 #ifdef ENABLE_LOGGING_AND_PROFILING | 707 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 728 if (!Log::IsEnabled() || !FLAG_log_code) return; | 708 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 729 LogMessageBuilder msg; | 709 LogMessageBuilder msg; |
| 730 msg.Append("%s,%s,", | 710 msg.Append("%s,%s,", |
| 731 kLogEventsNames[CODE_CREATION_EVENT], | 711 kLogEventsNames[CODE_CREATION_EVENT], |
| 732 kLogEventsNames[tag]); | 712 kLogEventsNames[tag]); |
| 733 msg.AppendAddress(code->address()); | 713 msg.AppendAddress(code->address()); |
| 734 msg.Append(",%d,\"%s", code->ExecutableSize(), ComputeMarker(code)); | 714 msg.Append(",%d,\"", code->ExecutableSize()); |
| 735 for (const char* p = comment; *p != '\0'; p++) { | 715 for (const char* p = comment; *p != '\0'; p++) { |
| 736 if (*p == '"') { | 716 if (*p == '"') { |
| 737 msg.Append('\\'); | 717 msg.Append('\\'); |
| 738 } | 718 } |
| 739 msg.Append(*p); | 719 msg.Append(*p); |
| 740 } | 720 } |
| 741 msg.Append('"'); | 721 msg.Append('"'); |
| 742 LowLevelCodeCreateEvent(code, &msg); | 722 LowLevelCodeCreateEvent(code, &msg); |
| 743 msg.Append('\n'); | 723 msg.Append('\n'); |
| 744 msg.WriteToLogFile(); | 724 msg.WriteToLogFile(); |
| 745 #endif | 725 #endif |
| 746 } | 726 } |
| 747 | 727 |
| 748 | 728 |
| 749 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name) { | 729 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 730 Code* code, |
| 731 String* name) { |
| 732 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 733 if (name != NULL) { |
| 734 SmartPointer<char> str = |
| 735 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 736 CodeCreateEvent(tag, code, *str); |
| 737 } else { |
| 738 CodeCreateEvent(tag, code, ""); |
| 739 } |
| 740 #endif |
| 741 } |
| 742 |
| 743 |
| 744 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 745 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 746 static const char* ComputeMarker(Code* code) { |
| 747 switch (code->kind()) { |
| 748 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 749 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 750 default: return ""; |
| 751 } |
| 752 } |
| 753 #endif |
| 754 |
| 755 |
| 756 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 757 Code* code, |
| 758 SharedFunctionInfo* shared, |
| 759 String* name) { |
| 750 #ifdef ENABLE_LOGGING_AND_PROFILING | 760 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 751 if (!Log::IsEnabled() || !FLAG_log_code) return; | 761 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 762 if (code == Builtins::builtin(Builtins::LazyCompile)) return; |
| 752 LogMessageBuilder msg; | 763 LogMessageBuilder msg; |
| 753 SmartPointer<char> str = | 764 SmartPointer<char> str = |
| 754 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 765 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 755 msg.Append("%s,%s,", | 766 msg.Append("%s,%s,", |
| 756 kLogEventsNames[CODE_CREATION_EVENT], | 767 kLogEventsNames[CODE_CREATION_EVENT], |
| 757 kLogEventsNames[tag]); | 768 kLogEventsNames[tag]); |
| 758 msg.AppendAddress(code->address()); | 769 msg.AppendAddress(code->address()); |
| 759 msg.Append(",%d,\"%s%s\"", code->ExecutableSize(), ComputeMarker(code), *str); | 770 msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); |
| 771 msg.AppendAddress(shared->address()); |
| 772 msg.Append(",%s", ComputeMarker(code)); |
| 760 LowLevelCodeCreateEvent(code, &msg); | 773 LowLevelCodeCreateEvent(code, &msg); |
| 761 msg.Append('\n'); | 774 msg.Append('\n'); |
| 762 msg.WriteToLogFile(); | 775 msg.WriteToLogFile(); |
| 763 #endif | 776 #endif |
| 764 } | 777 } |
| 765 | 778 |
| 766 | 779 |
| 780 // Although, it is possible to extract source and line from |
| 781 // the SharedFunctionInfo object, we left it to caller |
| 782 // to leave logging functions free from heap allocations. |
| 767 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 783 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 768 Code* code, String* name, | 784 Code* code, |
| 785 SharedFunctionInfo* shared, |
| 769 String* source, int line) { | 786 String* source, int line) { |
| 770 #ifdef ENABLE_LOGGING_AND_PROFILING | 787 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 771 if (!Log::IsEnabled() || !FLAG_log_code) return; | 788 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 772 LogMessageBuilder msg; | 789 LogMessageBuilder msg; |
| 773 SmartPointer<char> str = | 790 SmartPointer<char> name = |
| 774 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 791 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 775 SmartPointer<char> sourcestr = | 792 SmartPointer<char> sourcestr = |
| 776 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 793 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 777 msg.Append("%s,%s,", | 794 msg.Append("%s,%s,", |
| 778 kLogEventsNames[CODE_CREATION_EVENT], | 795 kLogEventsNames[CODE_CREATION_EVENT], |
| 779 kLogEventsNames[tag]); | 796 kLogEventsNames[tag]); |
| 780 msg.AppendAddress(code->address()); | 797 msg.AppendAddress(code->address()); |
| 781 msg.Append(",%d,\"%s%s %s:%d\"", | 798 msg.Append(",%d,\"%s %s:%d\",", |
| 782 code->ExecutableSize(), | 799 code->ExecutableSize(), |
| 783 ComputeMarker(code), | 800 *name, |
| 784 *str, | |
| 785 *sourcestr, | 801 *sourcestr, |
| 786 line); | 802 line); |
| 803 msg.AppendAddress(shared->address()); |
| 804 msg.Append(",%s", ComputeMarker(code)); |
| 787 LowLevelCodeCreateEvent(code, &msg); | 805 LowLevelCodeCreateEvent(code, &msg); |
| 788 msg.Append('\n'); | 806 msg.Append('\n'); |
| 789 msg.WriteToLogFile(); | 807 msg.WriteToLogFile(); |
| 790 #endif | 808 #endif |
| 791 } | 809 } |
| 792 | 810 |
| 793 | 811 |
| 794 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { | 812 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { |
| 795 #ifdef ENABLE_LOGGING_AND_PROFILING | 813 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 796 if (!Log::IsEnabled() || !FLAG_log_code) return; | 814 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 LogMessageBuilder msg; | 874 LogMessageBuilder msg; |
| 857 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 875 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| 858 msg.AppendAddress(addr); | 876 msg.AppendAddress(addr); |
| 859 msg.Append(",%d", pos); | 877 msg.Append(",%d", pos); |
| 860 msg.Append('\n'); | 878 msg.Append('\n'); |
| 861 msg.WriteToLogFile(); | 879 msg.WriteToLogFile(); |
| 862 #endif | 880 #endif |
| 863 } | 881 } |
| 864 | 882 |
| 865 | 883 |
| 866 void Logger::FunctionCreateEvent(JSFunction* function) { | 884 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { |
| 867 #ifdef ENABLE_LOGGING_AND_PROFILING | 885 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 868 // This function can be called from GC iterators (during Scavenge, | 886 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); |
| 869 // MC, and MS), so marking bits can be set on objects. That's | |
| 870 // why unchecked accessors are used here. | |
| 871 if (!Log::IsEnabled() || !FLAG_log_code) return; | |
| 872 LogMessageBuilder msg; | |
| 873 msg.Append("%s,", kLogEventsNames[FUNCTION_CREATION_EVENT]); | |
| 874 msg.AppendAddress(function->address()); | |
| 875 msg.Append(','); | |
| 876 msg.AppendAddress(function->unchecked_code()->address()); | |
| 877 msg.Append('\n'); | |
| 878 msg.WriteToLogFile(); | |
| 879 #endif | |
| 880 } | |
| 881 | |
| 882 | |
| 883 void Logger::FunctionCreateEventFromMove(JSFunction* function) { | |
| 884 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 885 if (function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile)) { | |
| 886 FunctionCreateEvent(function); | |
| 887 } | |
| 888 #endif | |
| 889 } | |
| 890 | |
| 891 | |
| 892 void Logger::FunctionMoveEvent(Address from, Address to) { | |
| 893 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 894 MoveEventInternal(FUNCTION_MOVE_EVENT, from, to); | |
| 895 #endif | |
| 896 } | |
| 897 | |
| 898 | |
| 899 void Logger::FunctionDeleteEvent(Address from) { | |
| 900 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 901 DeleteEventInternal(FUNCTION_DELETE_EVENT, from); | |
| 902 #endif | 887 #endif |
| 903 } | 888 } |
| 904 | 889 |
| 905 | 890 |
| 906 #ifdef ENABLE_LOGGING_AND_PROFILING | 891 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 907 void Logger::MoveEventInternal(LogEventsAndTags event, | 892 void Logger::MoveEventInternal(LogEventsAndTags event, |
| 908 Address from, | 893 Address from, |
| 909 Address to) { | 894 Address to) { |
| 910 if (!Log::IsEnabled() || !FLAG_log_code) return; | 895 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 911 LogMessageBuilder msg; | 896 LogMessageBuilder msg; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 | 1096 |
| 1112 #ifdef ENABLE_LOGGING_AND_PROFILING | 1097 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1113 void Logger::TickEvent(TickSample* sample, bool overflow) { | 1098 void Logger::TickEvent(TickSample* sample, bool overflow) { |
| 1114 if (!Log::IsEnabled() || !FLAG_prof) return; | 1099 if (!Log::IsEnabled() || !FLAG_prof) return; |
| 1115 LogMessageBuilder msg; | 1100 LogMessageBuilder msg; |
| 1116 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); | 1101 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); |
| 1117 msg.AppendAddress(sample->pc); | 1102 msg.AppendAddress(sample->pc); |
| 1118 msg.Append(','); | 1103 msg.Append(','); |
| 1119 msg.AppendAddress(sample->sp); | 1104 msg.AppendAddress(sample->sp); |
| 1120 msg.Append(','); | 1105 msg.Append(','); |
| 1121 msg.AppendAddress(sample->function); | 1106 msg.AppendAddress(sample->tos); |
| 1122 msg.Append(",%d", static_cast<int>(sample->state)); | 1107 msg.Append(",%d", static_cast<int>(sample->state)); |
| 1123 if (overflow) { | 1108 if (overflow) { |
| 1124 msg.Append(",overflow"); | 1109 msg.Append(",overflow"); |
| 1125 } | 1110 } |
| 1126 for (int i = 0; i < sample->frames_count; ++i) { | 1111 for (int i = 0; i < sample->frames_count; ++i) { |
| 1127 msg.Append(','); | 1112 msg.Append(','); |
| 1128 msg.AppendAddress(sample->stack[i]); | 1113 msg.AppendAddress(sample->stack[i]); |
| 1129 } | 1114 } |
| 1130 msg.Append('\n'); | 1115 msg.Append('\n'); |
| 1131 msg.WriteToLogFile(); | 1116 msg.WriteToLogFile(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 UncheckedIntEvent("open-tag", tag); | 1165 UncheckedIntEvent("open-tag", tag); |
| 1181 } | 1166 } |
| 1182 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { | 1167 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { |
| 1183 if (cpu_profiler_nesting_++ == 0) { | 1168 if (cpu_profiler_nesting_++ == 0) { |
| 1184 ++logging_nesting_; | 1169 ++logging_nesting_; |
| 1185 if (FLAG_prof_lazy) { | 1170 if (FLAG_prof_lazy) { |
| 1186 profiler_->Engage(); | 1171 profiler_->Engage(); |
| 1187 LOG(UncheckedStringEvent("profiler", "resume")); | 1172 LOG(UncheckedStringEvent("profiler", "resume")); |
| 1188 FLAG_log_code = true; | 1173 FLAG_log_code = true; |
| 1189 LogCompiledFunctions(); | 1174 LogCompiledFunctions(); |
| 1190 LogFunctionObjects(); | |
| 1191 LogAccessorCallbacks(); | 1175 LogAccessorCallbacks(); |
| 1192 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { | 1176 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { |
| 1193 ticker_->Start(); | 1177 ticker_->Start(); |
| 1194 } | 1178 } |
| 1195 } | 1179 } |
| 1196 profiler_->resume(); | 1180 profiler_->resume(); |
| 1197 } | 1181 } |
| 1198 } | 1182 } |
| 1199 if (flags & | 1183 if (flags & |
| 1200 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { | 1184 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 tag = Logger::STUB_TAG; | 1290 tag = Logger::STUB_TAG; |
| 1307 break; | 1291 break; |
| 1308 case Code::BUILTIN: | 1292 case Code::BUILTIN: |
| 1309 description = "A builtin from the snapshot"; | 1293 description = "A builtin from the snapshot"; |
| 1310 tag = Logger::BUILTIN_TAG; | 1294 tag = Logger::BUILTIN_TAG; |
| 1311 break; | 1295 break; |
| 1312 case Code::KEYED_LOAD_IC: | 1296 case Code::KEYED_LOAD_IC: |
| 1313 description = "A keyed load IC from the snapshot"; | 1297 description = "A keyed load IC from the snapshot"; |
| 1314 tag = Logger::KEYED_LOAD_IC_TAG; | 1298 tag = Logger::KEYED_LOAD_IC_TAG; |
| 1315 break; | 1299 break; |
| 1300 case Code::KEYED_EXTERNAL_ARRAY_LOAD_IC: |
| 1301 description = "A keyed external array load IC from the snapshot"; |
| 1302 tag = Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG; |
| 1303 break; |
| 1316 case Code::LOAD_IC: | 1304 case Code::LOAD_IC: |
| 1317 description = "A load IC from the snapshot"; | 1305 description = "A load IC from the snapshot"; |
| 1318 tag = Logger::LOAD_IC_TAG; | 1306 tag = Logger::LOAD_IC_TAG; |
| 1319 break; | 1307 break; |
| 1320 case Code::STORE_IC: | 1308 case Code::STORE_IC: |
| 1321 description = "A store IC from the snapshot"; | 1309 description = "A store IC from the snapshot"; |
| 1322 tag = Logger::STORE_IC_TAG; | 1310 tag = Logger::STORE_IC_TAG; |
| 1323 break; | 1311 break; |
| 1324 case Code::KEYED_STORE_IC: | 1312 case Code::KEYED_STORE_IC: |
| 1325 description = "A keyed store IC from the snapshot"; | 1313 description = "A keyed store IC from the snapshot"; |
| 1326 tag = Logger::KEYED_STORE_IC_TAG; | 1314 tag = Logger::KEYED_STORE_IC_TAG; |
| 1327 break; | 1315 break; |
| 1316 case Code::KEYED_EXTERNAL_ARRAY_STORE_IC: |
| 1317 description = "A keyed external array store IC from the snapshot"; |
| 1318 tag = Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG; |
| 1319 break; |
| 1328 case Code::CALL_IC: | 1320 case Code::CALL_IC: |
| 1329 description = "A call IC from the snapshot"; | 1321 description = "A call IC from the snapshot"; |
| 1330 tag = Logger::CALL_IC_TAG; | 1322 tag = Logger::CALL_IC_TAG; |
| 1331 break; | 1323 break; |
| 1332 case Code::KEYED_CALL_IC: | 1324 case Code::KEYED_CALL_IC: |
| 1333 description = "A keyed call IC from the snapshot"; | 1325 description = "A keyed call IC from the snapshot"; |
| 1334 tag = Logger::KEYED_CALL_IC_TAG; | 1326 tag = Logger::KEYED_CALL_IC_TAG; |
| 1335 break; | 1327 break; |
| 1336 } | 1328 } |
| 1337 PROFILE(CodeCreateEvent(tag, code_object, description)); | 1329 PROFILE(CodeCreateEvent(tag, code_object, description)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 void Logger::LogCompiledFunctions() { | 1373 void Logger::LogCompiledFunctions() { |
| 1382 HandleScope scope; | 1374 HandleScope scope; |
| 1383 const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); | 1375 const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); |
| 1384 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); | 1376 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); |
| 1385 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); | 1377 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); |
| 1386 EnumerateCompiledFunctions(sfis.start(), code_objects.start()); | 1378 EnumerateCompiledFunctions(sfis.start(), code_objects.start()); |
| 1387 | 1379 |
| 1388 // During iteration, there can be heap allocation due to | 1380 // During iteration, there can be heap allocation due to |
| 1389 // GetScriptLineNumber call. | 1381 // GetScriptLineNumber call. |
| 1390 for (int i = 0; i < compiled_funcs_count; ++i) { | 1382 for (int i = 0; i < compiled_funcs_count; ++i) { |
| 1383 if (*code_objects[i] == Builtins::builtin(Builtins::LazyCompile)) continue; |
| 1391 Handle<SharedFunctionInfo> shared = sfis[i]; | 1384 Handle<SharedFunctionInfo> shared = sfis[i]; |
| 1392 Handle<String> name(String::cast(shared->name())); | 1385 Handle<String> func_name(shared->DebugName()); |
| 1393 Handle<String> func_name(name->length() > 0 ? | |
| 1394 *name : shared->inferred_name()); | |
| 1395 if (shared->script()->IsScript()) { | 1386 if (shared->script()->IsScript()) { |
| 1396 Handle<Script> script(Script::cast(shared->script())); | 1387 Handle<Script> script(Script::cast(shared->script())); |
| 1397 if (script->name()->IsString()) { | 1388 if (script->name()->IsString()) { |
| 1398 Handle<String> script_name(String::cast(script->name())); | 1389 Handle<String> script_name(String::cast(script->name())); |
| 1399 int line_num = GetScriptLineNumber(script, shared->start_position()); | 1390 int line_num = GetScriptLineNumber(script, shared->start_position()); |
| 1400 if (line_num > 0) { | 1391 if (line_num > 0) { |
| 1401 PROFILE(CodeCreateEvent( | 1392 PROFILE(CodeCreateEvent( |
| 1402 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), | 1393 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), |
| 1403 *code_objects[i], *func_name, | 1394 *code_objects[i], *shared, |
| 1404 *script_name, line_num + 1)); | 1395 *script_name, line_num + 1)); |
| 1405 } else { | 1396 } else { |
| 1406 // Can't distinguish eval and script here, so always use Script. | 1397 // Can't distinguish eval and script here, so always use Script. |
| 1407 PROFILE(CodeCreateEvent( | 1398 PROFILE(CodeCreateEvent( |
| 1408 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), | 1399 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), |
| 1409 *code_objects[i], *script_name)); | 1400 *code_objects[i], *shared, *script_name)); |
| 1410 } | 1401 } |
| 1411 } else { | 1402 } else { |
| 1412 PROFILE(CodeCreateEvent( | 1403 PROFILE(CodeCreateEvent( |
| 1413 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), | 1404 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), |
| 1414 *code_objects[i], *func_name)); | 1405 *code_objects[i], *shared, *func_name)); |
| 1415 } | 1406 } |
| 1416 } else if (shared->IsApiFunction()) { | 1407 } else if (shared->IsApiFunction()) { |
| 1417 // API function. | 1408 // API function. |
| 1418 FunctionTemplateInfo* fun_data = shared->get_api_func_data(); | 1409 FunctionTemplateInfo* fun_data = shared->get_api_func_data(); |
| 1419 Object* raw_call_data = fun_data->call_code(); | 1410 Object* raw_call_data = fun_data->call_code(); |
| 1420 if (!raw_call_data->IsUndefined()) { | 1411 if (!raw_call_data->IsUndefined()) { |
| 1421 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1412 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 1422 Object* callback_obj = call_data->callback(); | 1413 Object* callback_obj = call_data->callback(); |
| 1423 Address entry_point = v8::ToCData<Address>(callback_obj); | 1414 Address entry_point = v8::ToCData<Address>(callback_obj); |
| 1424 PROFILE(CallbackEvent(*func_name, entry_point)); | 1415 PROFILE(CallbackEvent(*func_name, entry_point)); |
| 1425 } | 1416 } |
| 1426 } else { | 1417 } else { |
| 1427 PROFILE(CodeCreateEvent( | 1418 PROFILE(CodeCreateEvent( |
| 1428 Logger::LAZY_COMPILE_TAG, *code_objects[i], *func_name)); | 1419 Logger::LAZY_COMPILE_TAG, *code_objects[i], *shared, *func_name)); |
| 1429 } | 1420 } |
| 1430 } | 1421 } |
| 1431 } | 1422 } |
| 1432 | 1423 |
| 1433 | 1424 |
| 1434 void Logger::LogFunctionObjects() { | |
| 1435 AssertNoAllocation no_alloc; | |
| 1436 HeapIterator iterator; | |
| 1437 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | |
| 1438 if (!obj->IsJSFunction()) continue; | |
| 1439 JSFunction* jsf = JSFunction::cast(obj); | |
| 1440 if (!jsf->is_compiled()) continue; | |
| 1441 PROFILE(FunctionCreateEvent(jsf)); | |
| 1442 } | |
| 1443 } | |
| 1444 | |
| 1445 | |
| 1446 void Logger::LogAccessorCallbacks() { | 1425 void Logger::LogAccessorCallbacks() { |
| 1447 AssertNoAllocation no_alloc; | 1426 AssertNoAllocation no_alloc; |
| 1448 HeapIterator iterator; | 1427 HeapIterator iterator; |
| 1449 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1428 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1450 if (!obj->IsAccessorInfo()) continue; | 1429 if (!obj->IsAccessorInfo()) continue; |
| 1451 AccessorInfo* ai = AccessorInfo::cast(obj); | 1430 AccessorInfo* ai = AccessorInfo::cast(obj); |
| 1452 if (!ai->name()->IsString()) continue; | 1431 if (!ai->name()->IsString()) continue; |
| 1453 String* name = String::cast(ai->name()); | 1432 String* name = String::cast(ai->name()); |
| 1454 Address getter_entry = v8::ToCData<Address>(ai->getter()); | 1433 Address getter_entry = v8::ToCData<Address>(ai->getter()); |
| 1455 if (getter_entry != 0) { | 1434 if (getter_entry != 0) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 } | 1607 } |
| 1629 // Otherwise, if the sliding state window computation has not been | 1608 // Otherwise, if the sliding state window computation has not been |
| 1630 // started we do it now. | 1609 // started we do it now. |
| 1631 if (sliding_state_window_ == NULL) { | 1610 if (sliding_state_window_ == NULL) { |
| 1632 sliding_state_window_ = new SlidingStateWindow(); | 1611 sliding_state_window_ = new SlidingStateWindow(); |
| 1633 } | 1612 } |
| 1634 #endif | 1613 #endif |
| 1635 } | 1614 } |
| 1636 | 1615 |
| 1637 } } // namespace v8::internal | 1616 } } // namespace v8::internal |
| OLD | NEW |