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