Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: src/profile-generator.cc

Issue 18478002: Revert "Correctly report callstack when current function is FunctionCall builtin" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 || (tag_ == entry->tag_ 228 || (tag_ == entry->tag_
229 && shared_id_ == entry->shared_id_ 229 && shared_id_ == entry->shared_id_
230 && (shared_id_ != 0 230 && (shared_id_ != 0
231 || (name_prefix_ == entry->name_prefix_ 231 || (name_prefix_ == entry->name_prefix_
232 && name_ == entry->name_ 232 && name_ == entry->name_
233 && resource_name_ == entry->resource_name_ 233 && resource_name_ == entry->resource_name_
234 && line_number_ == entry->line_number_))); 234 && line_number_ == entry->line_number_)));
235 } 235 }
236 236
237 237
238 void CodeEntry::SetBuiltinId(Builtins::Name id) {
239 tag_ = Logger::BUILTIN_TAG;
240 builtin_id_ = id;
241 }
242
243
244 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { 238 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
245 HashMap::Entry* map_entry = 239 HashMap::Entry* map_entry =
246 children_.Lookup(entry, CodeEntryHash(entry), false); 240 children_.Lookup(entry, CodeEntryHash(entry), false);
247 return map_entry != NULL ? 241 return map_entry != NULL ?
248 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; 242 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL;
249 } 243 }
250 244
251 245
252 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { 246 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) {
253 HashMap::Entry* map_entry = 247 HashMap::Entry* map_entry =
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 static_cast<unsigned>(kWallTimeQueryIntervalMs * ticks_per_ms_); 840 static_cast<unsigned>(kWallTimeQueryIntervalMs * ticks_per_ms_);
847 } 841 }
848 842
849 843
850 const char* const ProfileGenerator::kAnonymousFunctionName = 844 const char* const ProfileGenerator::kAnonymousFunctionName =
851 "(anonymous function)"; 845 "(anonymous function)";
852 const char* const ProfileGenerator::kProgramEntryName = 846 const char* const ProfileGenerator::kProgramEntryName =
853 "(program)"; 847 "(program)";
854 const char* const ProfileGenerator::kGarbageCollectorEntryName = 848 const char* const ProfileGenerator::kGarbageCollectorEntryName =
855 "(garbage collector)"; 849 "(garbage collector)";
856 const char* const ProfileGenerator::kUnresolvedFunctionName =
857 "(unresolved function)";
858 850
859 851
860 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles) 852 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
861 : profiles_(profiles), 853 : profiles_(profiles),
862 program_entry_( 854 program_entry_(
863 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kProgramEntryName)), 855 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kProgramEntryName)),
864 gc_entry_( 856 gc_entry_(
865 profiles->NewCodeEntry(Logger::BUILTIN_TAG, 857 profiles->NewCodeEntry(Logger::BUILTIN_TAG,
866 kGarbageCollectorEntryName)), 858 kGarbageCollectorEntryName)) {
867 unresolved_entry_(
868 profiles->NewCodeEntry(Logger::FUNCTION_TAG,
869 kUnresolvedFunctionName)) {
870 } 859 }
871 860
872 861
873 void ProfileGenerator::RecordTickSample(const TickSample& sample) { 862 void ProfileGenerator::RecordTickSample(const TickSample& sample) {
874 // Allocate space for stack frames + pc + function + vm-state. 863 // Allocate space for stack frames + pc + function + vm-state.
875 ScopedVector<CodeEntry*> entries(sample.frames_count + 3); 864 ScopedVector<CodeEntry*> entries(sample.frames_count + 3);
876 // As actual number of decoded code entries may vary, initialize 865 // As actual number of decoded code entries may vary, initialize
877 // entries vector with NULL values. 866 // entries vector with NULL values.
878 CodeEntry** entry = entries.start(); 867 CodeEntry** entry = entries.start();
879 memset(entry, 0, entries.length() * sizeof(*entry)); 868 memset(entry, 0, entries.length() * sizeof(*entry));
880 if (sample.pc != NULL) { 869 if (sample.pc != NULL) {
870 Address start;
871 CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start);
872 // If pc is in the function code before it set up stack frame or after the
873 // frame was destroyed SafeStackFrameIterator incorrectly thinks that
874 // ebp contains return address of the current function and skips caller's
875 // frame. Check for this case and just skip such samples.
876 if (pc_entry) {
877 List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
878 if (ranges) {
879 Code* code = Code::cast(HeapObject::FromAddress(start));
880 int pc_offset = static_cast<int>(sample.pc - code->instruction_start());
881 for (int i = 0; i < ranges->length(); i++) {
882 OffsetRange& range = ranges->at(i);
883 if (range.from <= pc_offset && pc_offset < range.to) {
884 return;
885 }
886 }
887 }
888 }
889 *entry++ = pc_entry;
890
881 if (sample.has_external_callback) { 891 if (sample.has_external_callback) {
882 // Don't use PC when in external callback code, as it can point 892 // Don't use PC when in external callback code, as it can point
883 // inside callback's code, and we will erroneously report 893 // inside callback's code, and we will erroneously report
884 // that a callback calls itself. 894 // that a callback calls itself.
895 *(entries.start()) = NULL;
885 *entry++ = code_map_.FindEntry(sample.external_callback); 896 *entry++ = code_map_.FindEntry(sample.external_callback);
886 } else {
887 Address start;
888 CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start);
889 // If pc is in the function code before it set up stack frame or after the
890 // frame was destroyed SafeStackFrameIterator incorrectly thinks that
891 // ebp contains return address of the current function and skips caller's
892 // frame. Check for this case and just skip such samples.
893 if (pc_entry) {
894 List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
895 if (ranges) {
896 Code* code = Code::cast(HeapObject::FromAddress(start));
897 int pc_offset = static_cast<int>(
898 sample.pc - code->instruction_start());
899 for (int i = 0; i < ranges->length(); i++) {
900 OffsetRange& range = ranges->at(i);
901 if (range.from <= pc_offset && pc_offset < range.to) {
902 return;
903 }
904 }
905 }
906 *entry++ = pc_entry;
907
908 if (pc_entry->builtin_id() == Builtins::kFunctionCall) {
909 // When current function is FunctionCall builtin tos is sometimes
910 // address of the function that invoked it but sometimes it's one
911 // of the arguments. We simply replace the frame with 'unknown' entry.
912 *entry++ = unresolved_entry_;
913 }
914 }
915 } 897 }
916 898
917 for (const Address* stack_pos = sample.stack, 899 for (const Address* stack_pos = sample.stack,
918 *stack_end = stack_pos + sample.frames_count; 900 *stack_end = stack_pos + sample.frames_count;
919 stack_pos != stack_end; 901 stack_pos != stack_end;
920 ++stack_pos) { 902 ++stack_pos) {
921 *entry++ = code_map_.FindEntry(*stack_pos); 903 *entry++ = code_map_.FindEntry(*stack_pos);
922 } 904 }
923 } 905 }
924 906
925 if (FLAG_prof_browser_mode) { 907 if (FLAG_prof_browser_mode) {
926 bool no_symbolized_entries = true; 908 bool no_symbolized_entries = true;
927 for (CodeEntry** e = entries.start(); e != entry; ++e) { 909 for (CodeEntry** e = entries.start(); e != entry; ++e) {
928 if (*e != NULL) { 910 if (*e != NULL) {
929 no_symbolized_entries = false; 911 no_symbolized_entries = false;
930 break; 912 break;
931 } 913 }
932 } 914 }
933 // If no frames were symbolized, put the VM state entry in. 915 // If no frames were symbolized, put the VM state entry in.
934 if (no_symbolized_entries) { 916 if (no_symbolized_entries) {
935 *entry++ = EntryForVMState(sample.state); 917 *entry++ = EntryForVMState(sample.state);
936 } 918 }
937 } 919 }
938 920
939 profiles_->AddPathToCurrentProfiles(entries); 921 profiles_->AddPathToCurrentProfiles(entries);
940 } 922 }
941 923
942 924
943 } } // namespace v8::internal 925 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698