erik.corry@gmail.com | c3b670f | 2011-10-05 21:44:48 +0000 | [diff] [blame] | 1 | // Copyright 2011 the V8 project authors. All rights reserved. |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 2 | // Redistribution and use in source and binary forms, with or without |
| 3 | // modification, are permitted provided that the following conditions are |
| 4 | // met: |
| 5 | // |
| 6 | // * Redistributions of source code must retain the above copyright |
| 7 | // notice, this list of conditions and the following disclaimer. |
| 8 | // * Redistributions in binary form must reproduce the above |
| 9 | // copyright notice, this list of conditions and the following |
| 10 | // disclaimer in the documentation and/or other materials provided |
| 11 | // with the distribution. |
| 12 | // * Neither the name of Google Inc. nor the names of its |
| 13 | // contributors may be used to endorse or promote products derived |
| 14 | // from this software without specific prior written permission. |
| 15 | // |
| 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | |
| 28 | #ifndef V8_PROFILE_GENERATOR_H_ |
| 29 | #define V8_PROFILE_GENERATOR_H_ |
| 30 | |
lrn@chromium.org | 1c09276 | 2011-05-09 09:42:16 +0000 | [diff] [blame] | 31 | #include "allocation.h" |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 32 | #include "hashmap.h" |
ager@chromium.org | 2cc82ae | 2010-06-14 07:35:38 +0000 | [diff] [blame] | 33 | #include "../include/v8-profiler.h" |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 34 | |
| 35 | namespace v8 { |
| 36 | namespace internal { |
| 37 | |
jkummerow@chromium.org | 4e308cf | 2013-05-17 13:39:16 +0000 | [diff] [blame] | 38 | struct OffsetRange; |
| 39 | |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 40 | // Provides a storage of strings allocated in C++ heap, to hold them |
| 41 | // forever, even if they disappear from JS heap or external storage. |
| 42 | class StringsStorage { |
| 43 | public: |
hpayer@chromium.org | c5d4971 | 2013-09-11 08:25:48 +0000 | [diff] [blame] | 44 | explicit StringsStorage(Heap* heap); |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 45 | ~StringsStorage(); |
| 46 | |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 47 | const char* GetCopy(const char* src); |
| 48 | const char* GetFormatted(const char* format, ...); |
| 49 | const char* GetVFormatted(const char* format, va_list args); |
ulan@chromium.org | 750145a | 2013-03-07 15:14:13 +0000 | [diff] [blame] | 50 | const char* GetName(Name* name); |
vegorov@chromium.org | 4284196 | 2010-10-18 11:18:59 +0000 | [diff] [blame] | 51 | const char* GetName(int index); |
ulan@chromium.org | 750145a | 2013-03-07 15:14:13 +0000 | [diff] [blame] | 52 | inline const char* GetFunctionName(Name* name); |
erik.corry@gmail.com | 145eff5 | 2010-08-23 11:36:18 +0000 | [diff] [blame] | 53 | inline const char* GetFunctionName(const char* name); |
mmassi@chromium.org | 7028c05 | 2012-06-13 11:51:58 +0000 | [diff] [blame] | 54 | size_t GetUsedMemorySize() const; |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 55 | |
| 56 | private: |
danno@chromium.org | c612e02 | 2011-11-10 11:38:15 +0000 | [diff] [blame] | 57 | static const int kMaxNameSize = 1024; |
| 58 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 59 | static bool StringsMatch(void* key1, void* key2) { |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 60 | return strcmp(reinterpret_cast<char*>(key1), |
| 61 | reinterpret_cast<char*>(key2)) == 0; |
| 62 | } |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 63 | const char* AddOrDisposeString(char* str, uint32_t hash); |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 64 | |
ricow@chromium.org | 4980dff | 2010-07-19 08:33:45 +0000 | [diff] [blame] | 65 | // Mapping of strings by String::Hash to const char* strings. |
hpayer@chromium.org | c5d4971 | 2013-09-11 08:25:48 +0000 | [diff] [blame] | 66 | uint32_t hash_seed_; |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 67 | HashMap names_; |
| 68 | |
| 69 | DISALLOW_COPY_AND_ASSIGN(StringsStorage); |
| 70 | }; |
| 71 | |
| 72 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 73 | class CodeEntry { |
| 74 | public: |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 75 | // CodeEntry doesn't own name strings, just references them. |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 76 | inline CodeEntry(Logger::LogEventsAndTags tag, |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 77 | const char* name, |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 78 | const char* name_prefix = CodeEntry::kEmptyNamePrefix, |
mstarzinger@chromium.org | 1510d58 | 2013-06-28 14:00:48 +0000 | [diff] [blame] | 79 | const char* resource_name = CodeEntry::kEmptyResourceName, |
mvstanton@chromium.org | dd6d9ee | 2013-10-11 10:35:37 +0000 | [diff] [blame] | 80 | int line_number = v8::CpuProfileNode::kNoLineNumberInfo, |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 81 | int column_number = v8::CpuProfileNode::kNoColumnNumberInfo); |
jkummerow@chromium.org | 4e308cf | 2013-05-17 13:39:16 +0000 | [diff] [blame] | 82 | ~CodeEntry(); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 83 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 84 | bool is_js_function() const { return is_js_function_tag(tag_); } |
| 85 | const char* name_prefix() const { return name_prefix_; } |
| 86 | bool has_name_prefix() const { return name_prefix_[0] != '\0'; } |
| 87 | const char* name() const { return name_; } |
| 88 | const char* resource_name() const { return resource_name_; } |
| 89 | int line_number() const { return line_number_; } |
mvstanton@chromium.org | dd6d9ee | 2013-10-11 10:35:37 +0000 | [diff] [blame] | 90 | int column_number() const { return column_number_; } |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 91 | void set_shared_id(int shared_id) { shared_id_ = shared_id; } |
| 92 | int script_id() const { return script_id_; } |
| 93 | void set_script_id(int script_id) { script_id_ = script_id; } |
| 94 | void set_bailout_reason(const char* bailout_reason) { |
jkummerow@chromium.org | 2c9426b | 2013-09-05 16:31:13 +0000 | [diff] [blame] | 95 | bailout_reason_ = bailout_reason; |
| 96 | } |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 97 | const char* bailout_reason() const { return bailout_reason_; } |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 98 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 99 | static inline bool is_js_function_tag(Logger::LogEventsAndTags tag); |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 100 | |
jkummerow@chromium.org | 4e308cf | 2013-05-17 13:39:16 +0000 | [diff] [blame] | 101 | List<OffsetRange>* no_frame_ranges() const { return no_frame_ranges_; } |
| 102 | void set_no_frame_ranges(List<OffsetRange>* ranges) { |
| 103 | no_frame_ranges_ = ranges; |
| 104 | } |
| 105 | |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 106 | void SetBuiltinId(Builtins::Name id); |
| 107 | Builtins::Name builtin_id() const { return builtin_id_; } |
| 108 | |
fschneider@chromium.org | c20610a | 2010-09-22 09:44:58 +0000 | [diff] [blame] | 109 | uint32_t GetCallUid() const; |
| 110 | bool IsSameAs(CodeEntry* entry) const; |
erik.corry@gmail.com | 9dfbea4 | 2010-05-21 12:58:28 +0000 | [diff] [blame] | 111 | |
sgjesse@chromium.org | ea88ce9 | 2011-03-23 11:19:56 +0000 | [diff] [blame] | 112 | static const char* const kEmptyNamePrefix; |
mstarzinger@chromium.org | 1510d58 | 2013-06-28 14:00:48 +0000 | [diff] [blame] | 113 | static const char* const kEmptyResourceName; |
jkummerow@chromium.org | 2c9426b | 2013-09-05 16:31:13 +0000 | [diff] [blame] | 114 | static const char* const kEmptyBailoutReason; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 115 | |
| 116 | private: |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 117 | Logger::LogEventsAndTags tag_ : 8; |
| 118 | Builtins::Name builtin_id_ : 8; |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 119 | const char* name_prefix_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 120 | const char* name_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 121 | const char* resource_name_; |
| 122 | int line_number_; |
mvstanton@chromium.org | dd6d9ee | 2013-10-11 10:35:37 +0000 | [diff] [blame] | 123 | int column_number_; |
fschneider@chromium.org | 3a5fd78 | 2011-02-24 10:10:44 +0000 | [diff] [blame] | 124 | int shared_id_; |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 125 | int script_id_; |
jkummerow@chromium.org | 4e308cf | 2013-05-17 13:39:16 +0000 | [diff] [blame] | 126 | List<OffsetRange>* no_frame_ranges_; |
jkummerow@chromium.org | 2c9426b | 2013-09-05 16:31:13 +0000 | [diff] [blame] | 127 | const char* bailout_reason_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 128 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 129 | DISALLOW_COPY_AND_ASSIGN(CodeEntry); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 130 | }; |
| 131 | |
| 132 | |
ricow@chromium.org | c9c8082 | 2010-04-21 08:22:37 +0000 | [diff] [blame] | 133 | class ProfileTree; |
| 134 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 135 | class ProfileNode { |
| 136 | public: |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 137 | inline ProfileNode(ProfileTree* tree, CodeEntry* entry); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 138 | |
| 139 | ProfileNode* FindChild(CodeEntry* entry); |
| 140 | ProfileNode* FindOrAddChild(CodeEntry* entry); |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 141 | void IncrementSelfTicks() { ++self_ticks_; } |
| 142 | void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 143 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 144 | CodeEntry* entry() const { return entry_; } |
| 145 | unsigned self_ticks() const { return self_ticks_; } |
| 146 | const List<ProfileNode*>* children() const { return &children_list_; } |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 147 | unsigned id() const { return id_; } |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 148 | |
| 149 | void Print(int indent); |
| 150 | |
| 151 | private: |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 152 | static bool CodeEntriesMatch(void* entry1, void* entry2) { |
fschneider@chromium.org | c20610a | 2010-09-22 09:44:58 +0000 | [diff] [blame] | 153 | return reinterpret_cast<CodeEntry*>(entry1)->IsSameAs( |
| 154 | reinterpret_cast<CodeEntry*>(entry2)); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 155 | } |
| 156 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 157 | static uint32_t CodeEntryHash(CodeEntry* entry) { |
fschneider@chromium.org | c20610a | 2010-09-22 09:44:58 +0000 | [diff] [blame] | 158 | return entry->GetCallUid(); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 159 | } |
| 160 | |
ricow@chromium.org | c9c8082 | 2010-04-21 08:22:37 +0000 | [diff] [blame] | 161 | ProfileTree* tree_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 162 | CodeEntry* entry_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 163 | unsigned self_ticks_; |
ricow@chromium.org | 4980dff | 2010-07-19 08:33:45 +0000 | [diff] [blame] | 164 | // Mapping from CodeEntry* to ProfileNode* |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 165 | HashMap children_; |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 166 | List<ProfileNode*> children_list_; |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 167 | unsigned id_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 168 | |
| 169 | DISALLOW_COPY_AND_ASSIGN(ProfileNode); |
| 170 | }; |
| 171 | |
| 172 | |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 173 | class ProfileTree { |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 174 | public: |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 175 | ProfileTree(); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 176 | ~ProfileTree(); |
| 177 | |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 178 | ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 179 | void AddPathFromStart(const Vector<CodeEntry*>& path); |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 180 | ProfileNode* root() const { return root_; } |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 181 | unsigned next_node_id() { return next_node_id_++; } |
| 182 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 183 | void Print() { |
| 184 | root_->Print(0); |
| 185 | } |
| 186 | |
| 187 | private: |
| 188 | template <typename Callback> |
erik.corry@gmail.com | 9dfbea4 | 2010-05-21 12:58:28 +0000 | [diff] [blame] | 189 | void TraverseDepthFirst(Callback* callback); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 190 | |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 191 | CodeEntry root_entry_; |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 192 | unsigned next_node_id_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 193 | ProfileNode* root_; |
| 194 | |
| 195 | DISALLOW_COPY_AND_ASSIGN(ProfileTree); |
| 196 | }; |
| 197 | |
| 198 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 199 | class CpuProfile { |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 200 | public: |
danno@chromium.org | d3c4210 | 2013-08-01 16:58:23 +0000 | [diff] [blame] | 201 | CpuProfile(const char* title, unsigned uid, bool record_samples); |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 202 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 203 | // Add pc -> ... -> main() call path to the profile. |
| 204 | void AddPath(const Vector<CodeEntry*>& path); |
danno@chromium.org | d3c4210 | 2013-08-01 16:58:23 +0000 | [diff] [blame] | 205 | void CalculateTotalTicksAndSamplingRate(); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 206 | |
danno@chromium.org | 89acc0b | 2013-08-09 20:55:58 +0000 | [diff] [blame] | 207 | const char* title() const { return title_; } |
| 208 | unsigned uid() const { return uid_; } |
| 209 | const ProfileTree* top_down() const { return &top_down_; } |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 210 | |
danno@chromium.org | 89acc0b | 2013-08-09 20:55:58 +0000 | [diff] [blame] | 211 | int samples_count() const { return samples_.length(); } |
| 212 | ProfileNode* sample(int index) const { return samples_.at(index); } |
| 213 | |
jkummerow@chromium.org | dc94e19 | 2013-08-30 11:35:42 +0000 | [diff] [blame] | 214 | Time start_time() const { return start_time_; } |
| 215 | Time end_time() const { return end_time_; } |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 216 | |
ricow@chromium.org | c9c8082 | 2010-04-21 08:22:37 +0000 | [diff] [blame] | 217 | void UpdateTicksScale(); |
| 218 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 219 | void Print(); |
| 220 | |
| 221 | private: |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 222 | const char* title_; |
| 223 | unsigned uid_; |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 224 | bool record_samples_; |
jkummerow@chromium.org | dc94e19 | 2013-08-30 11:35:42 +0000 | [diff] [blame] | 225 | Time start_time_; |
| 226 | Time end_time_; |
| 227 | ElapsedTimer timer_; |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 228 | List<ProfileNode*> samples_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 229 | ProfileTree top_down_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 230 | |
| 231 | DISALLOW_COPY_AND_ASSIGN(CpuProfile); |
| 232 | }; |
| 233 | |
| 234 | |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 235 | class CodeMap { |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 236 | public: |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 237 | CodeMap() : next_shared_id_(1) { } |
lrn@chromium.org | 34e6078 | 2011-09-15 07:25:40 +0000 | [diff] [blame] | 238 | void AddCode(Address addr, CodeEntry* entry, unsigned size); |
| 239 | void MoveCode(Address from, Address to); |
jkummerow@chromium.org | 4e308cf | 2013-05-17 13:39:16 +0000 | [diff] [blame] | 240 | CodeEntry* FindEntry(Address addr, Address* start = NULL); |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 241 | int GetSharedId(Address addr); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 242 | |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 243 | void Print(); |
| 244 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 245 | private: |
| 246 | struct CodeEntryInfo { |
| 247 | CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) |
| 248 | : entry(an_entry), size(a_size) { } |
| 249 | CodeEntry* entry; |
| 250 | unsigned size; |
| 251 | }; |
| 252 | |
| 253 | struct CodeTreeConfig { |
| 254 | typedef Address Key; |
| 255 | typedef CodeEntryInfo Value; |
| 256 | static const Key kNoKey; |
svenpanne@chromium.org | a8bb4d9 | 2011-10-10 13:20:40 +0000 | [diff] [blame] | 257 | static const Value NoValue() { return CodeEntryInfo(NULL, 0); } |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 258 | static int Compare(const Key& a, const Key& b) { |
| 259 | return a < b ? -1 : (a > b ? 1 : 0); |
| 260 | } |
| 261 | }; |
| 262 | typedef SplayTree<CodeTreeConfig> CodeTree; |
| 263 | |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 264 | class CodeTreePrinter { |
| 265 | public: |
| 266 | void Call(const Address& key, const CodeEntryInfo& value); |
| 267 | }; |
| 268 | |
lrn@chromium.org | 34e6078 | 2011-09-15 07:25:40 +0000 | [diff] [blame] | 269 | void DeleteAllCoveredCode(Address start, Address end); |
| 270 | |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 271 | // Fake CodeEntry pointer to distinguish shared function entries. |
| 272 | static CodeEntry* const kSharedFunctionCodeEntry; |
fschneider@chromium.org | 3a5fd78 | 2011-02-24 10:10:44 +0000 | [diff] [blame] | 273 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 274 | CodeTree tree_; |
whesse@chromium.org | b08986c | 2011-03-14 16:13:42 +0000 | [diff] [blame] | 275 | int next_shared_id_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 276 | |
| 277 | DISALLOW_COPY_AND_ASSIGN(CodeMap); |
| 278 | }; |
| 279 | |
| 280 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 281 | class CpuProfilesCollection { |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 282 | public: |
hpayer@chromium.org | c5d4971 | 2013-09-11 08:25:48 +0000 | [diff] [blame] | 283 | explicit CpuProfilesCollection(Heap* heap); |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 284 | ~CpuProfilesCollection(); |
| 285 | |
mstarzinger@chromium.org | f705b50 | 2013-04-04 11:38:09 +0000 | [diff] [blame] | 286 | bool StartProfiling(const char* title, unsigned uid, bool record_samples); |
danno@chromium.org | d3c4210 | 2013-08-01 16:58:23 +0000 | [diff] [blame] | 287 | CpuProfile* StopProfiling(const char* title); |
mstarzinger@chromium.org | e0e1b0d | 2013-07-08 08:38:06 +0000 | [diff] [blame] | 288 | List<CpuProfile*>* profiles() { return &finished_profiles_; } |
ulan@chromium.org | 750145a | 2013-03-07 15:14:13 +0000 | [diff] [blame] | 289 | const char* GetName(Name* name) { |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 290 | return function_and_resource_names_.GetName(name); |
| 291 | } |
vegorov@chromium.org | 4284196 | 2010-10-18 11:18:59 +0000 | [diff] [blame] | 292 | const char* GetName(int args_count) { |
| 293 | return function_and_resource_names_.GetName(args_count); |
| 294 | } |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 295 | const char* GetFunctionName(Name* name) { |
| 296 | return function_and_resource_names_.GetFunctionName(name); |
| 297 | } |
| 298 | const char* GetFunctionName(const char* name) { |
| 299 | return function_and_resource_names_.GetFunctionName(name); |
| 300 | } |
vegorov@chromium.org | 26c16f8 | 2010-08-11 13:41:03 +0000 | [diff] [blame] | 301 | bool IsLastProfile(const char* title); |
sgjesse@chromium.org | ea88ce9 | 2011-03-23 11:19:56 +0000 | [diff] [blame] | 302 | void RemoveProfile(CpuProfile* profile); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 303 | |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 304 | CodeEntry* NewCodeEntry( |
| 305 | Logger::LogEventsAndTags tag, |
| 306 | const char* name, |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 307 | const char* name_prefix = CodeEntry::kEmptyNamePrefix, |
| 308 | const char* resource_name = CodeEntry::kEmptyResourceName, |
mvstanton@chromium.org | dd6d9ee | 2013-10-11 10:35:37 +0000 | [diff] [blame] | 309 | int line_number = v8::CpuProfileNode::kNoLineNumberInfo, |
| 310 | int column_number = v8::CpuProfileNode::kNoColumnNumberInfo); |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 311 | |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 312 | // Called from profile generator thread. |
| 313 | void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path); |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 314 | |
ricow@chromium.org | d236f4d | 2010-09-01 06:52:08 +0000 | [diff] [blame] | 315 | // Limits the number of profiles that can be simultaneously collected. |
| 316 | static const int kMaxSimultaneousProfiles = 100; |
| 317 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 318 | private: |
vegorov@chromium.org | 2356e6f | 2010-06-09 09:38:56 +0000 | [diff] [blame] | 319 | StringsStorage function_and_resource_names_; |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 320 | List<CodeEntry*> code_entries_; |
mstarzinger@chromium.org | e0e1b0d | 2013-07-08 08:38:06 +0000 | [diff] [blame] | 321 | List<CpuProfile*> finished_profiles_; |
lrn@chromium.org | 25156de | 2010-04-06 13:10:27 +0000 | [diff] [blame] | 322 | |
| 323 | // Accessed by VM thread and profile generator thread. |
| 324 | List<CpuProfile*> current_profiles_; |
mstarzinger@chromium.org | e900018 | 2013-09-03 11:25:39 +0000 | [diff] [blame] | 325 | Semaphore current_profiles_semaphore_; |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 326 | |
| 327 | DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); |
| 328 | }; |
| 329 | |
| 330 | |
| 331 | class ProfileGenerator { |
| 332 | public: |
| 333 | explicit ProfileGenerator(CpuProfilesCollection* profiles); |
| 334 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 335 | void RecordTickSample(const TickSample& sample); |
| 336 | |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 337 | CodeMap* code_map() { return &code_map_; } |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 338 | |
sgjesse@chromium.org | ea88ce9 | 2011-03-23 11:19:56 +0000 | [diff] [blame] | 339 | static const char* const kAnonymousFunctionName; |
| 340 | static const char* const kProgramEntryName; |
danno@chromium.org | 5940060 | 2013-08-13 17:09:37 +0000 | [diff] [blame] | 341 | static const char* const kIdleEntryName; |
sgjesse@chromium.org | ea88ce9 | 2011-03-23 11:19:56 +0000 | [diff] [blame] | 342 | static const char* const kGarbageCollectorEntryName; |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 343 | // Used to represent frames for which we have no reliable way to |
| 344 | // detect function. |
| 345 | static const char* const kUnresolvedFunctionName; |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 346 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 347 | private: |
mstarzinger@chromium.org | a2e1a40 | 2013-10-15 08:25:05 +0000 | [diff] [blame] | 348 | CodeEntry* EntryForVMState(StateTag tag); |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 349 | |
whesse@chromium.org | cec079d | 2010-03-22 14:44:04 +0000 | [diff] [blame] | 350 | CpuProfilesCollection* profiles_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 351 | CodeMap code_map_; |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 352 | CodeEntry* program_entry_; |
danno@chromium.org | 5940060 | 2013-08-13 17:09:37 +0000 | [diff] [blame] | 353 | CodeEntry* idle_entry_; |
ager@chromium.org | 357bf65 | 2010-04-12 11:30:10 +0000 | [diff] [blame] | 354 | CodeEntry* gc_entry_; |
jkummerow@chromium.org | 93a47f4 | 2013-07-02 14:43:41 +0000 | [diff] [blame] | 355 | CodeEntry* unresolved_entry_; |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 356 | |
| 357 | DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); |
| 358 | }; |
| 359 | |
ager@chromium.org | 2cc82ae | 2010-06-14 07:35:38 +0000 | [diff] [blame] | 360 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 361 | } } // namespace v8::internal |
| 362 | |
fschneider@chromium.org | 086aac6 | 2010-03-17 13:18:24 +0000 | [diff] [blame] | 363 | #endif // V8_PROFILE_GENERATOR_H_ |