OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/profile-generator-inl.h" | 7 #include "src/profile-generator-inl.h" |
8 | 8 |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
11 #include "src/deoptimizer.h" | |
12 #include "src/global-handles.h" | 11 #include "src/global-handles.h" |
13 #include "src/sampler.h" | 12 #include "src/sampler.h" |
14 #include "src/scopeinfo.h" | 13 #include "src/scopeinfo.h" |
15 #include "src/unicode.h" | 14 #include "src/unicode.h" |
16 | 15 |
17 namespace v8 { | 16 namespace v8 { |
18 namespace internal { | 17 namespace internal { |
19 | 18 |
20 | 19 |
21 bool StringsStorage::StringsMatch(void* key1, void* key2) { | 20 bool StringsStorage::StringsMatch(void* key1, void* key2) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 if (it == pc_offset_map_.end()) { | 151 if (it == pc_offset_map_.end()) { |
153 if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo; | 152 if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo; |
154 return (--pc_offset_map_.end())->second; | 153 return (--pc_offset_map_.end())->second; |
155 } | 154 } |
156 return it->second; | 155 return it->second; |
157 } | 156 } |
158 | 157 |
159 | 158 |
160 const char* const CodeEntry::kEmptyNamePrefix = ""; | 159 const char* const CodeEntry::kEmptyNamePrefix = ""; |
161 const char* const CodeEntry::kEmptyResourceName = ""; | 160 const char* const CodeEntry::kEmptyResourceName = ""; |
162 const char* const CodeEntry::kEmptyBailoutReason = | 161 const char* const CodeEntry::kEmptyBailoutReason = ""; |
163 GetBailoutReason(BailoutReason::kNoReason); | |
164 const char* const CodeEntry::kNoDeoptReason = ""; | |
165 | 162 |
166 | 163 |
167 CodeEntry::~CodeEntry() { | 164 CodeEntry::~CodeEntry() { |
168 delete no_frame_ranges_; | 165 delete no_frame_ranges_; |
169 delete line_info_; | 166 delete line_info_; |
170 } | 167 } |
171 | 168 |
172 | 169 |
173 uint32_t CodeEntry::GetCallUid() const { | 170 uint32_t CodeEntry::GetCallUid() const { |
174 uint32_t hash = ComputeIntegerHash(tag(), v8::internal::kZeroHashSeed); | 171 uint32_t hash = ComputeIntegerHash(tag(), v8::internal::kZeroHashSeed); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 205 |
209 | 206 |
210 int CodeEntry::GetSourceLine(int pc_offset) const { | 207 int CodeEntry::GetSourceLine(int pc_offset) const { |
211 if (line_info_ && !line_info_->empty()) { | 208 if (line_info_ && !line_info_->empty()) { |
212 return line_info_->GetSourceLineNumber(pc_offset); | 209 return line_info_->GetSourceLineNumber(pc_offset); |
213 } | 210 } |
214 return v8::CpuProfileNode::kNoLineNumberInfo; | 211 return v8::CpuProfileNode::kNoLineNumberInfo; |
215 } | 212 } |
216 | 213 |
217 | 214 |
218 void ProfileNode::CollectDeoptInfo(CodeEntry* entry) { | |
219 deopt_infos_.Add(DeoptInfo(entry->deopt_reason(), entry->deopt_location())); | |
220 entry->clear_deopt_info(); | |
221 } | |
222 | |
223 | |
224 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { | 215 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { |
225 HashMap::Entry* map_entry = | 216 HashMap::Entry* map_entry = |
226 children_.Lookup(entry, CodeEntryHash(entry), false); | 217 children_.Lookup(entry, CodeEntryHash(entry), false); |
227 return map_entry != NULL ? | 218 return map_entry != NULL ? |
228 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; | 219 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; |
229 } | 220 } |
230 | 221 |
231 | 222 |
232 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { | 223 ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { |
233 HashMap::Entry* map_entry = | 224 HashMap::Entry* map_entry = |
234 children_.Lookup(entry, CodeEntryHash(entry), true); | 225 children_.Lookup(entry, CodeEntryHash(entry), true); |
235 ProfileNode* node = reinterpret_cast<ProfileNode*>(map_entry->value); | 226 if (map_entry->value == NULL) { |
236 if (node == NULL) { | |
237 // New node added. | 227 // New node added. |
238 node = new ProfileNode(tree_, entry); | 228 ProfileNode* new_node = new ProfileNode(tree_, entry); |
239 map_entry->value = node; | 229 map_entry->value = new_node; |
240 children_list_.Add(node); | 230 children_list_.Add(new_node); |
241 } | 231 } |
242 if (entry->has_deopt_info()) node->CollectDeoptInfo(entry); | 232 return reinterpret_cast<ProfileNode*>(map_entry->value); |
243 return node; | |
244 } | 233 } |
245 | 234 |
246 | 235 |
247 void ProfileNode::IncrementLineTicks(int src_line) { | 236 void ProfileNode::IncrementLineTicks(int src_line) { |
248 if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) return; | 237 if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) return; |
249 // Increment a hit counter of a certain source line. | 238 // Increment a hit counter of a certain source line. |
250 // Add a new source line if not found. | 239 // Add a new source line if not found. |
251 HashMap::Entry* e = | 240 HashMap::Entry* e = |
252 line_ticks_.Lookup(reinterpret_cast<void*>(src_line), src_line, true); | 241 line_ticks_.Lookup(reinterpret_cast<void*>(src_line), src_line, true); |
253 DCHECK(e); | 242 DCHECK(e); |
(...skipping 18 matching lines...) Expand all Loading... |
272 static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->key)); | 261 static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->key)); |
273 entry->hit_count = | 262 entry->hit_count = |
274 static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->value)); | 263 static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->value)); |
275 } | 264 } |
276 | 265 |
277 return true; | 266 return true; |
278 } | 267 } |
279 | 268 |
280 | 269 |
281 void ProfileNode::Print(int indent) { | 270 void ProfileNode::Print(int indent) { |
282 base::OS::Print("%5u %*s %s%s %d #%d", self_ticks_, indent, "", | 271 base::OS::Print("%5u %*s %s%s %d #%d %s", self_ticks_, indent, "", |
283 entry_->name_prefix(), entry_->name(), entry_->script_id(), | 272 entry_->name_prefix(), entry_->name(), entry_->script_id(), |
284 id()); | 273 id(), entry_->bailout_reason()); |
285 if (entry_->resource_name()[0] != '\0') | 274 if (entry_->resource_name()[0] != '\0') |
286 base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number()); | 275 base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number()); |
287 base::OS::Print("\n"); | 276 base::OS::Print("\n"); |
288 for (auto info : deopt_infos_) { | |
289 base::OS::Print("%*s deopted at %d with reason '%s'\n", indent + 10, "", | |
290 info.deopt_location, info.deopt_reason); | |
291 } | |
292 const char* bailout_reason = entry_->bailout_reason(); | |
293 if (bailout_reason != GetBailoutReason(BailoutReason::kNoReason)) { | |
294 base::OS::Print("%*s bailed out due to '%s'\n", indent + 10, "", | |
295 bailout_reason); | |
296 } | |
297 for (HashMap::Entry* p = children_.Start(); | 277 for (HashMap::Entry* p = children_.Start(); |
298 p != NULL; | 278 p != NULL; |
299 p = children_.Next(p)) { | 279 p = children_.Next(p)) { |
300 reinterpret_cast<ProfileNode*>(p->value)->Print(indent + 2); | 280 reinterpret_cast<ProfileNode*>(p->value)->Print(indent + 2); |
301 } | 281 } |
302 } | 282 } |
303 | 283 |
304 | 284 |
305 class DeleteNodesCallback { | 285 class DeleteNodesCallback { |
306 public: | 286 public: |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 case OTHER: | 738 case OTHER: |
759 case EXTERNAL: | 739 case EXTERNAL: |
760 return program_entry_; | 740 return program_entry_; |
761 case IDLE: | 741 case IDLE: |
762 return idle_entry_; | 742 return idle_entry_; |
763 default: return NULL; | 743 default: return NULL; |
764 } | 744 } |
765 } | 745 } |
766 | 746 |
767 } } // namespace v8::internal | 747 } } // namespace v8::internal |
OLD | NEW |