Chromium Code Reviews| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 | |
| 238 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { | 244 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { | 
| 239 HashMap::Entry* map_entry = | 245 HashMap::Entry* map_entry = | 
| 240 children_.Lookup(entry, CodeEntryHash(entry), false); | 246 children_.Lookup(entry, CodeEntryHash(entry), false); | 
| 241 return map_entry != NULL ? | 247 return map_entry != NULL ? | 
| 242 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; | 248 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; | 
| 243 } | 249 } | 
| 244 | 250 | 
| 245 | 251 | 
| 246 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { | 252 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { | 
| 247 HashMap::Entry* map_entry = | 253 HashMap::Entry* map_entry = | 
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 | 866 | 
| 861 | 867 | 
| 862 void ProfileGenerator::RecordTickSample(const TickSample& sample) { | 868 void ProfileGenerator::RecordTickSample(const TickSample& sample) { | 
| 863 // Allocate space for stack frames + pc + function + vm-state. | 869 // Allocate space for stack frames + pc + function + vm-state. | 
| 864 ScopedVector<CodeEntry*> entries(sample.frames_count + 3); | 870 ScopedVector<CodeEntry*> entries(sample.frames_count + 3); | 
| 865 // As actual number of decoded code entries may vary, initialize | 871 // As actual number of decoded code entries may vary, initialize | 
| 866 // entries vector with NULL values. | 872 // entries vector with NULL values. | 
| 867 CodeEntry** entry = entries.start(); | 873 CodeEntry** entry = entries.start(); | 
| 868 memset(entry, 0, entries.length() * sizeof(*entry)); | 874 memset(entry, 0, entries.length() * sizeof(*entry)); | 
| 869 if (sample.pc != NULL) { | 875 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 | |
| 891 if (sample.has_external_callback) { | 876 if (sample.has_external_callback) { | 
| 892 // Don't use PC when in external callback code, as it can point | 877 // Don't use PC when in external callback code, as it can point | 
| 893 // inside callback's code, and we will erroneously report | 878 // inside callback's code, and we will erroneously report | 
| 894 // that a callback calls itself. | 879 // that a callback calls itself. | 
| 895 *(entries.start()) = NULL; | |
| 896 *entry++ = code_map_.FindEntry(sample.external_callback); | 880 *entry++ = code_map_.FindEntry(sample.external_callback); | 
| 881 } else { | |
| 882 Address start; | |
| 883 CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start); | |
| 884 // If pc is in the function code before it set up stack frame or after the | |
| 885 // frame was destroyed SafeStackFrameIterator incorrectly thinks that | |
| 886 // ebp contains return address of the current function and skips caller's | |
| 887 // frame. Check for this case and just skip such samples. | |
| 888 if (pc_entry) { | |
| 889 List<OffsetRange>* ranges = pc_entry->no_frame_ranges(); | |
| 890 if (ranges) { | |
| 891 Code* code = Code::cast(HeapObject::FromAddress(start)); | |
| 892 int pc_offset = static_cast<int>( | |
| 893 sample.pc - code->instruction_start()); | |
| 894 for (int i = 0; i < ranges->length(); i++) { | |
| 895 OffsetRange& range = ranges->at(i); | |
| 896 if (range.from <= pc_offset && pc_offset < range.to) { | |
| 897 return; | |
| 898 } | |
| 899 } | |
| 900 } | |
| 901 *entry++ = pc_entry; | |
| 902 | |
| 903 if (pc_entry->builtin_id() == Builtins::kFunctionCall) { | |
| 904 // When current function is FunctionCall builtin tos is alway | |
| 
 
loislo
2013/07/01 12:00:20
tipo: alway
 
 | |
| 905 // address of the function that invoked it. | |
| 906 *entry++ = code_map_.FindEntry(sample.tos); | |
| 907 } | |
| 908 } | |
| 897 } | 909 } | 
| 898 | 910 | 
| 899 for (const Address* stack_pos = sample.stack, | 911 for (const Address* stack_pos = sample.stack, | 
| 900 *stack_end = stack_pos + sample.frames_count; | 912 *stack_end = stack_pos + sample.frames_count; | 
| 901 stack_pos != stack_end; | 913 stack_pos != stack_end; | 
| 902 ++stack_pos) { | 914 ++stack_pos) { | 
| 903 *entry++ = code_map_.FindEntry(*stack_pos); | 915 *entry++ = code_map_.FindEntry(*stack_pos); | 
| 904 } | 916 } | 
| 905 } | 917 } | 
| 906 | 918 | 
| 907 if (FLAG_prof_browser_mode) { | 919 if (FLAG_prof_browser_mode) { | 
| 908 bool no_symbolized_entries = true; | 920 bool no_symbolized_entries = true; | 
| 909 for (CodeEntry** e = entries.start(); e != entry; ++e) { | 921 for (CodeEntry** e = entries.start(); e != entry; ++e) { | 
| 910 if (*e != NULL) { | 922 if (*e != NULL) { | 
| 911 no_symbolized_entries = false; | 923 no_symbolized_entries = false; | 
| 912 break; | 924 break; | 
| 913 } | 925 } | 
| 914 } | 926 } | 
| 915 // If no frames were symbolized, put the VM state entry in. | 927 // If no frames were symbolized, put the VM state entry in. | 
| 916 if (no_symbolized_entries) { | 928 if (no_symbolized_entries) { | 
| 917 *entry++ = EntryForVMState(sample.state); | 929 *entry++ = EntryForVMState(sample.state); | 
| 918 } | 930 } | 
| 919 } | 931 } | 
| 920 | 932 | 
| 921 profiles_->AddPathToCurrentProfiles(entries); | 933 profiles_->AddPathToCurrentProfiles(entries); | 
| 922 } | 934 } | 
| 923 | 935 | 
| 924 | 936 | 
| 925 } } // namespace v8::internal | 937 } } // namespace v8::internal | 
| OLD | NEW |