| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 138 |
| 139 // Tells whether we are currently recording tick samples. | 139 // Tells whether we are currently recording tick samples. |
| 140 bool paused_; | 140 bool paused_; |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 | 143 |
| 144 // | 144 // |
| 145 // StackTracer implementation | 145 // StackTracer implementation |
| 146 // | 146 // |
| 147 void StackTracer::Trace(Isolate* isolate, TickSample* sample) { | 147 void StackTracer::Trace(Isolate* isolate, TickSample* sample) { |
| 148 sample->function = NULL; | 148 sample->tos = NULL; |
| 149 sample->frames_count = 0; | 149 sample->frames_count = 0; |
| 150 | 150 |
| 151 // Avoid collecting traces while doing GC. | 151 // Avoid collecting traces while doing GC. |
| 152 if (sample->state == GC) return; | 152 if (sample->state == GC) return; |
| 153 | 153 |
| 154 const Address js_entry_sp = | 154 const Address js_entry_sp = |
| 155 Isolate::js_entry_sp(isolate->thread_local_top()); | 155 Isolate::js_entry_sp(isolate->thread_local_top()); |
| 156 if (js_entry_sp == 0) { | 156 if (js_entry_sp == 0) { |
| 157 // Not executing JS now. | 157 // Not executing JS now. |
| 158 return; | 158 return; |
| 159 } | 159 } |
| 160 | 160 |
| 161 const Address function_address = | 161 // Sample potential return address value for frameless invocation of |
| 162 sample->fp + JavaScriptFrameConstants::kFunctionOffset; | 162 // stubs (we'll figure out later, if this value makes sense). |
| 163 if (SafeStackFrameIterator::IsWithinBounds(sample->sp, js_entry_sp, | 163 sample->tos = Memory::Address_at(sample->sp); |
| 164 function_address)) { | |
| 165 Object* object = Memory::Object_at(function_address); | |
| 166 if (object->IsHeapObject()) { | |
| 167 sample->function = HeapObject::cast(object)->address(); | |
| 168 } | |
| 169 } | |
| 170 | 164 |
| 171 int i = 0; | 165 int i = 0; |
| 172 const Address callback = isolate->external_callback(); | 166 const Address callback = isolate->external_callback(); |
| 173 // Surprisingly, PC can point _exactly_ to callback start, with good | 167 // Surprisingly, PC can point _exactly_ to callback start, with good |
| 174 // probability, and this will result in reporting fake nested | 168 // probability, and this will result in reporting fake nested |
| 175 // callback call. | 169 // callback call. |
| 176 if (callback != NULL && callback != sample->pc) { | 170 if (callback != NULL && callback != sample->pc) { |
| 177 sample->stack[i++] = callback; | 171 sample->stack[i++] = callback; |
| 178 } | 172 } |
| 179 | 173 |
| 180 SafeStackTraceFrameIterator it(isolate, | 174 SafeStackTraceFrameIterator it(isolate, |
| 181 sample->fp, sample->sp, | 175 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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 void Logger::SetterCallbackEvent(String* name, Address entry_point) { | 719 void Logger::SetterCallbackEvent(String* name, Address entry_point) { |
| 729 #ifdef ENABLE_LOGGING_AND_PROFILING | 720 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 730 if (!log_->IsEnabled() || !FLAG_log_code) return; | 721 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 731 SmartPointer<char> str = | 722 SmartPointer<char> str = |
| 732 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 723 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 733 CallbackEventInternal("set ", *str, entry_point); | 724 CallbackEventInternal("set ", *str, entry_point); |
| 734 #endif | 725 #endif |
| 735 } | 726 } |
| 736 | 727 |
| 737 | 728 |
| 738 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 739 static const char* ComputeMarker(Code* code) { | |
| 740 switch (code->kind()) { | |
| 741 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | |
| 742 case Code::OPTIMIZED_FUNCTION: return "*"; | |
| 743 default: return ""; | |
| 744 } | |
| 745 } | |
| 746 #endif | |
| 747 | |
| 748 | |
| 749 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 729 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 750 Code* code, | 730 Code* code, |
| 751 const char* comment) { | 731 const char* comment) { |
| 752 #ifdef ENABLE_LOGGING_AND_PROFILING | 732 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 753 if (!log_->IsEnabled() || !FLAG_log_code) return; | 733 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 754 LogMessageBuilder msg(this); | 734 LogMessageBuilder msg(this); |
| 755 msg.Append("%s,%s,", | 735 msg.Append("%s,%s,", |
| 756 kLogEventsNames[CODE_CREATION_EVENT], | 736 kLogEventsNames[CODE_CREATION_EVENT], |
| 757 kLogEventsNames[tag]); | 737 kLogEventsNames[tag]); |
| 758 msg.AppendAddress(code->address()); | 738 msg.AppendAddress(code->address()); |
| 759 msg.Append(",%d,\"%s", code->ExecutableSize(), ComputeMarker(code)); | 739 msg.Append(",%d,\"", code->ExecutableSize()); |
| 760 for (const char* p = comment; *p != '\0'; p++) { | 740 for (const char* p = comment; *p != '\0'; p++) { |
| 761 if (*p == '"') { | 741 if (*p == '"') { |
| 762 msg.Append('\\'); | 742 msg.Append('\\'); |
| 763 } | 743 } |
| 764 msg.Append(*p); | 744 msg.Append(*p); |
| 765 } | 745 } |
| 766 msg.Append('"'); | 746 msg.Append('"'); |
| 767 LowLevelCodeCreateEvent(code, &msg); | 747 LowLevelCodeCreateEvent(code, &msg); |
| 768 msg.Append('\n'); | 748 msg.Append('\n'); |
| 769 msg.WriteToLogFile(); | 749 msg.WriteToLogFile(); |
| 770 #endif | 750 #endif |
| 771 } | 751 } |
| 772 | 752 |
| 773 | 753 |
| 774 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name) { | 754 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 755 Code* code, |
| 756 String* name) { |
| 757 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 758 if (name != NULL) { |
| 759 SmartPointer<char> str = |
| 760 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 761 CodeCreateEvent(tag, code, *str); |
| 762 } else { |
| 763 CodeCreateEvent(tag, code, ""); |
| 764 } |
| 765 #endif |
| 766 } |
| 767 |
| 768 |
| 769 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 770 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 771 static const char* ComputeMarker(Code* code) { |
| 772 switch (code->kind()) { |
| 773 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 774 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 775 default: return ""; |
| 776 } |
| 777 } |
| 778 #endif |
| 779 |
| 780 |
| 781 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 782 Code* code, |
| 783 SharedFunctionInfo* shared, |
| 784 String* name) { |
| 775 #ifdef ENABLE_LOGGING_AND_PROFILING | 785 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 776 if (!log_->IsEnabled() || !FLAG_log_code) return; | 786 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 787 if (code == Isolate::Current()->builtins()->builtin( |
| 788 Builtins::LazyCompile)) |
| 789 return; |
| 790 |
| 777 LogMessageBuilder msg(this); | 791 LogMessageBuilder msg(this); |
| 778 SmartPointer<char> str = | 792 SmartPointer<char> str = |
| 779 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 793 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 780 msg.Append("%s,%s,", | 794 msg.Append("%s,%s,", |
| 781 kLogEventsNames[CODE_CREATION_EVENT], | 795 kLogEventsNames[CODE_CREATION_EVENT], |
| 782 kLogEventsNames[tag]); | 796 kLogEventsNames[tag]); |
| 783 msg.AppendAddress(code->address()); | 797 msg.AppendAddress(code->address()); |
| 784 msg.Append(",%d,\"%s%s\"", code->ExecutableSize(), ComputeMarker(code), *str); | 798 msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); |
| 799 msg.AppendAddress(shared->address()); |
| 800 msg.Append(",%s", ComputeMarker(code)); |
| 785 LowLevelCodeCreateEvent(code, &msg); | 801 LowLevelCodeCreateEvent(code, &msg); |
| 786 msg.Append('\n'); | 802 msg.Append('\n'); |
| 787 msg.WriteToLogFile(); | 803 msg.WriteToLogFile(); |
| 788 #endif | 804 #endif |
| 789 } | 805 } |
| 790 | 806 |
| 791 | 807 |
| 808 // Although, it is possible to extract source and line from |
| 809 // the SharedFunctionInfo object, we left it to caller |
| 810 // to leave logging functions free from heap allocations. |
| 792 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 811 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 793 Code* code, String* name, | 812 Code* code, |
| 813 SharedFunctionInfo* shared, |
| 794 String* source, int line) { | 814 String* source, int line) { |
| 795 #ifdef ENABLE_LOGGING_AND_PROFILING | 815 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 796 if (!log_->IsEnabled() || !FLAG_log_code) return; | 816 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 797 LogMessageBuilder msg(this); | 817 LogMessageBuilder msg(this); |
| 798 SmartPointer<char> str = | 818 SmartPointer<char> name = |
| 799 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 819 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 800 SmartPointer<char> sourcestr = | 820 SmartPointer<char> sourcestr = |
| 801 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 821 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 802 msg.Append("%s,%s,", | 822 msg.Append("%s,%s,", |
| 803 kLogEventsNames[CODE_CREATION_EVENT], | 823 kLogEventsNames[CODE_CREATION_EVENT], |
| 804 kLogEventsNames[tag]); | 824 kLogEventsNames[tag]); |
| 805 msg.AppendAddress(code->address()); | 825 msg.AppendAddress(code->address()); |
| 806 msg.Append(",%d,\"%s%s %s:%d\"", | 826 msg.Append(",%d,\"%s %s:%d\",", |
| 807 code->ExecutableSize(), | 827 code->ExecutableSize(), |
| 808 ComputeMarker(code), | 828 *name, |
| 809 *str, | |
| 810 *sourcestr, | 829 *sourcestr, |
| 811 line); | 830 line); |
| 831 msg.AppendAddress(shared->address()); |
| 832 msg.Append(",%s", ComputeMarker(code)); |
| 812 LowLevelCodeCreateEvent(code, &msg); | 833 LowLevelCodeCreateEvent(code, &msg); |
| 813 msg.Append('\n'); | 834 msg.Append('\n'); |
| 814 msg.WriteToLogFile(); | 835 msg.WriteToLogFile(); |
| 815 #endif | 836 #endif |
| 816 } | 837 } |
| 817 | 838 |
| 818 | 839 |
| 819 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { | 840 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { |
| 820 #ifdef ENABLE_LOGGING_AND_PROFILING | 841 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 821 if (!log_->IsEnabled() || !FLAG_log_code) return; | 842 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 LogMessageBuilder msg(this); | 902 LogMessageBuilder msg(this); |
| 882 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 903 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| 883 msg.AppendAddress(addr); | 904 msg.AppendAddress(addr); |
| 884 msg.Append(",%d", pos); | 905 msg.Append(",%d", pos); |
| 885 msg.Append('\n'); | 906 msg.Append('\n'); |
| 886 msg.WriteToLogFile(); | 907 msg.WriteToLogFile(); |
| 887 #endif | 908 #endif |
| 888 } | 909 } |
| 889 | 910 |
| 890 | 911 |
| 891 void Logger::FunctionCreateEvent(JSFunction* function) { | 912 void Logger::SFIMoveEvent(Address from, Address to) { |
| 892 #ifdef ENABLE_LOGGING_AND_PROFILING | 913 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 893 // This function can be called from GC iterators (during Scavenge, | 914 MoveEventInternal(SFI_MOVE_EVENT, from, to); |
| 894 // MC, and MS), so marking bits can be set on objects. That's | |
| 895 // why unchecked accessors are used here. | |
| 896 if (!log_->IsEnabled() || !FLAG_log_code) return; | |
| 897 LogMessageBuilder msg(this); | |
| 898 msg.Append("%s,", kLogEventsNames[FUNCTION_CREATION_EVENT]); | |
| 899 msg.AppendAddress(function->address()); | |
| 900 msg.Append(','); | |
| 901 msg.AppendAddress(function->unchecked_code()->address()); | |
| 902 msg.Append('\n'); | |
| 903 msg.WriteToLogFile(); | |
| 904 #endif | |
| 905 } | |
| 906 | |
| 907 | |
| 908 void Logger::FunctionCreateEventFromMove(Heap* heap, JSFunction* function) { | |
| 909 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 910 if (function->unchecked_code() != | |
| 911 heap->isolate()->builtins()->builtin(Builtins::LazyCompile)) { | |
| 912 FunctionCreateEvent(function); | |
| 913 } | |
| 914 #endif | |
| 915 } | |
| 916 | |
| 917 | |
| 918 void Logger::FunctionMoveEvent(Heap* heap, Address from, Address to) { | |
| 919 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 920 MoveEventInternal(FUNCTION_MOVE_EVENT, from, to); | |
| 921 #endif | |
| 922 } | |
| 923 | |
| 924 | |
| 925 void Logger::FunctionDeleteEvent(Address from) { | |
| 926 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 927 DeleteEventInternal(FUNCTION_DELETE_EVENT, from); | |
| 928 #endif | 915 #endif |
| 929 } | 916 } |
| 930 | 917 |
| 931 | 918 |
| 932 #ifdef ENABLE_LOGGING_AND_PROFILING | 919 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 933 void Logger::MoveEventInternal(LogEventsAndTags event, | 920 void Logger::MoveEventInternal(LogEventsAndTags event, |
| 934 Address from, | 921 Address from, |
| 935 Address to) { | 922 Address to) { |
| 936 if (!log_->IsEnabled() || !FLAG_log_code) return; | 923 if (!log_->IsEnabled() || !FLAG_log_code) return; |
| 937 LogMessageBuilder msg(this); | 924 LogMessageBuilder msg(this); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 | 1124 |
| 1138 #ifdef ENABLE_LOGGING_AND_PROFILING | 1125 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1139 void Logger::TickEvent(TickSample* sample, bool overflow) { | 1126 void Logger::TickEvent(TickSample* sample, bool overflow) { |
| 1140 if (!log_->IsEnabled() || !FLAG_prof) return; | 1127 if (!log_->IsEnabled() || !FLAG_prof) return; |
| 1141 LogMessageBuilder msg(this); | 1128 LogMessageBuilder msg(this); |
| 1142 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); | 1129 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); |
| 1143 msg.AppendAddress(sample->pc); | 1130 msg.AppendAddress(sample->pc); |
| 1144 msg.Append(','); | 1131 msg.Append(','); |
| 1145 msg.AppendAddress(sample->sp); | 1132 msg.AppendAddress(sample->sp); |
| 1146 msg.Append(','); | 1133 msg.Append(','); |
| 1147 msg.AppendAddress(sample->function); | 1134 msg.AppendAddress(sample->tos); |
| 1148 msg.Append(",%d", static_cast<int>(sample->state)); | 1135 msg.Append(",%d", static_cast<int>(sample->state)); |
| 1149 if (overflow) { | 1136 if (overflow) { |
| 1150 msg.Append(",overflow"); | 1137 msg.Append(",overflow"); |
| 1151 } | 1138 } |
| 1152 for (int i = 0; i < sample->frames_count; ++i) { | 1139 for (int i = 0; i < sample->frames_count; ++i) { |
| 1153 msg.Append(','); | 1140 msg.Append(','); |
| 1154 msg.AppendAddress(sample->stack[i]); | 1141 msg.AppendAddress(sample->stack[i]); |
| 1155 } | 1142 } |
| 1156 msg.Append('\n'); | 1143 msg.Append('\n'); |
| 1157 msg.WriteToLogFile(); | 1144 msg.WriteToLogFile(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 UncheckedIntEvent("open-tag", tag); | 1193 UncheckedIntEvent("open-tag", tag); |
| 1207 } | 1194 } |
| 1208 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { | 1195 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { |
| 1209 if (cpu_profiler_nesting_++ == 0) { | 1196 if (cpu_profiler_nesting_++ == 0) { |
| 1210 ++logging_nesting_; | 1197 ++logging_nesting_; |
| 1211 if (FLAG_prof_lazy) { | 1198 if (FLAG_prof_lazy) { |
| 1212 profiler_->Engage(); | 1199 profiler_->Engage(); |
| 1213 LOG(UncheckedStringEvent("profiler", "resume")); | 1200 LOG(UncheckedStringEvent("profiler", "resume")); |
| 1214 FLAG_log_code = true; | 1201 FLAG_log_code = true; |
| 1215 LogCompiledFunctions(); | 1202 LogCompiledFunctions(); |
| 1216 LogFunctionObjects(); | |
| 1217 LogAccessorCallbacks(); | 1203 LogAccessorCallbacks(); |
| 1218 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { | 1204 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { |
| 1219 ticker_->Start(); | 1205 ticker_->Start(); |
| 1220 } | 1206 } |
| 1221 } | 1207 } |
| 1222 profiler_->resume(); | 1208 profiler_->resume(); |
| 1223 } | 1209 } |
| 1224 } | 1210 } |
| 1225 if (flags & | 1211 if (flags & |
| 1226 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { | 1212 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 void Logger::LogCompiledFunctions() { | 1392 void Logger::LogCompiledFunctions() { |
| 1407 HandleScope scope; | 1393 HandleScope scope; |
| 1408 const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); | 1394 const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); |
| 1409 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); | 1395 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); |
| 1410 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); | 1396 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); |
| 1411 EnumerateCompiledFunctions(sfis.start(), code_objects.start()); | 1397 EnumerateCompiledFunctions(sfis.start(), code_objects.start()); |
| 1412 | 1398 |
| 1413 // During iteration, there can be heap allocation due to | 1399 // During iteration, there can be heap allocation due to |
| 1414 // GetScriptLineNumber call. | 1400 // GetScriptLineNumber call. |
| 1415 for (int i = 0; i < compiled_funcs_count; ++i) { | 1401 for (int i = 0; i < compiled_funcs_count; ++i) { |
| 1402 if (*code_objects[i] == Isolate::Current()->builtins()->builtin( |
| 1403 Builtins::LazyCompile)) |
| 1404 continue; |
| 1416 Handle<SharedFunctionInfo> shared = sfis[i]; | 1405 Handle<SharedFunctionInfo> shared = sfis[i]; |
| 1417 Handle<String> name(String::cast(shared->name())); | 1406 Handle<String> func_name(shared->DebugName()); |
| 1418 Handle<String> func_name(name->length() > 0 ? | |
| 1419 *name : shared->inferred_name()); | |
| 1420 if (shared->script()->IsScript()) { | 1407 if (shared->script()->IsScript()) { |
| 1421 Handle<Script> script(Script::cast(shared->script())); | 1408 Handle<Script> script(Script::cast(shared->script())); |
| 1422 if (script->name()->IsString()) { | 1409 if (script->name()->IsString()) { |
| 1423 Handle<String> script_name(String::cast(script->name())); | 1410 Handle<String> script_name(String::cast(script->name())); |
| 1424 int line_num = GetScriptLineNumber(script, shared->start_position()); | 1411 int line_num = GetScriptLineNumber(script, shared->start_position()); |
| 1425 if (line_num > 0) { | 1412 if (line_num > 0) { |
| 1426 PROFILE(CodeCreateEvent( | 1413 PROFILE(CodeCreateEvent( |
| 1427 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), | 1414 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), |
| 1428 *code_objects[i], *func_name, | 1415 *code_objects[i], *shared, |
| 1429 *script_name, line_num + 1)); | 1416 *script_name, line_num + 1)); |
| 1430 } else { | 1417 } else { |
| 1431 // Can't distinguish eval and script here, so always use Script. | 1418 // Can't distinguish eval and script here, so always use Script. |
| 1432 PROFILE(CodeCreateEvent( | 1419 PROFILE(CodeCreateEvent( |
| 1433 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), | 1420 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), |
| 1434 *code_objects[i], *script_name)); | 1421 *code_objects[i], *shared, *script_name)); |
| 1435 } | 1422 } |
| 1436 } else { | 1423 } else { |
| 1437 PROFILE(CodeCreateEvent( | 1424 PROFILE(CodeCreateEvent( |
| 1438 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), | 1425 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), |
| 1439 *code_objects[i], *func_name)); | 1426 *code_objects[i], *shared, *func_name)); |
| 1440 } | 1427 } |
| 1441 } else if (shared->IsApiFunction()) { | 1428 } else if (shared->IsApiFunction()) { |
| 1442 // API function. | 1429 // API function. |
| 1443 FunctionTemplateInfo* fun_data = shared->get_api_func_data(); | 1430 FunctionTemplateInfo* fun_data = shared->get_api_func_data(); |
| 1444 Object* raw_call_data = fun_data->call_code(); | 1431 Object* raw_call_data = fun_data->call_code(); |
| 1445 if (!raw_call_data->IsUndefined()) { | 1432 if (!raw_call_data->IsUndefined()) { |
| 1446 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1433 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 1447 Object* callback_obj = call_data->callback(); | 1434 Object* callback_obj = call_data->callback(); |
| 1448 Address entry_point = v8::ToCData<Address>(callback_obj); | 1435 Address entry_point = v8::ToCData<Address>(callback_obj); |
| 1449 PROFILE(CallbackEvent(*func_name, entry_point)); | 1436 PROFILE(CallbackEvent(*func_name, entry_point)); |
| 1450 } | 1437 } |
| 1451 } else { | 1438 } else { |
| 1452 PROFILE(CodeCreateEvent( | 1439 PROFILE(CodeCreateEvent( |
| 1453 Logger::LAZY_COMPILE_TAG, *code_objects[i], *func_name)); | 1440 Logger::LAZY_COMPILE_TAG, *code_objects[i], *shared, *func_name)); |
| 1454 } | 1441 } |
| 1455 } | 1442 } |
| 1456 } | 1443 } |
| 1457 | 1444 |
| 1458 | 1445 |
| 1459 void Logger::LogFunctionObjects() { | |
| 1460 AssertNoAllocation no_alloc; | |
| 1461 HeapIterator iterator; | |
| 1462 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | |
| 1463 if (!obj->IsJSFunction()) continue; | |
| 1464 JSFunction* jsf = JSFunction::cast(obj); | |
| 1465 if (!jsf->is_compiled()) continue; | |
| 1466 PROFILE(FunctionCreateEvent(jsf)); | |
| 1467 } | |
| 1468 } | |
| 1469 | |
| 1470 | |
| 1471 void Logger::LogAccessorCallbacks() { | 1446 void Logger::LogAccessorCallbacks() { |
| 1472 AssertNoAllocation no_alloc; | 1447 AssertNoAllocation no_alloc; |
| 1473 HeapIterator iterator; | 1448 HeapIterator iterator; |
| 1474 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1449 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1475 if (!obj->IsAccessorInfo()) continue; | 1450 if (!obj->IsAccessorInfo()) continue; |
| 1476 AccessorInfo* ai = AccessorInfo::cast(obj); | 1451 AccessorInfo* ai = AccessorInfo::cast(obj); |
| 1477 if (!ai->name()->IsString()) continue; | 1452 if (!ai->name()->IsString()) continue; |
| 1478 String* name = String::cast(ai->name()); | 1453 String* name = String::cast(ai->name()); |
| 1479 Address getter_entry = v8::ToCData<Address>(ai->getter()); | 1454 Address getter_entry = v8::ToCData<Address>(ai->getter()); |
| 1480 if (getter_entry != 0) { | 1455 if (getter_entry != 0) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { | 1632 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { |
| 1658 ASSERT(sampler->IsActive()); | 1633 ASSERT(sampler->IsActive()); |
| 1659 ScopedLock lock(mutex_); | 1634 ScopedLock lock(mutex_); |
| 1660 ASSERT(active_samplers_ != NULL); | 1635 ASSERT(active_samplers_ != NULL); |
| 1661 bool removed = active_samplers_->RemoveElement(sampler); | 1636 bool removed = active_samplers_->RemoveElement(sampler); |
| 1662 ASSERT(removed); | 1637 ASSERT(removed); |
| 1663 USE(removed); | 1638 USE(removed); |
| 1664 } | 1639 } |
| 1665 | 1640 |
| 1666 } } // namespace v8::internal | 1641 } } // namespace v8::internal |
| OLD | NEW |