| 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 23 matching lines...) Expand all Loading... |
| 34 #include "sampler.h" | 34 #include "sampler.h" |
| 35 #include "global-handles.h" | 35 #include "global-handles.h" |
| 36 #include "scopeinfo.h" | 36 #include "scopeinfo.h" |
| 37 #include "unicode.h" | 37 #include "unicode.h" |
| 38 #include "zone-inl.h" | 38 #include "zone-inl.h" |
| 39 | 39 |
| 40 namespace v8 { | 40 namespace v8 { |
| 41 namespace internal { | 41 namespace internal { |
| 42 | 42 |
| 43 | 43 |
| 44 TokenEnumerator::TokenEnumerator() | |
| 45 : token_locations_(4), | |
| 46 token_removed_(4) { | |
| 47 } | |
| 48 | |
| 49 | |
| 50 TokenEnumerator::~TokenEnumerator() { | |
| 51 Isolate* isolate = Isolate::Current(); | |
| 52 for (int i = 0; i < token_locations_.length(); ++i) { | |
| 53 if (!token_removed_[i]) { | |
| 54 isolate->global_handles()->ClearWeakness(token_locations_[i]); | |
| 55 isolate->global_handles()->Destroy(token_locations_[i]); | |
| 56 } | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 | |
| 61 int TokenEnumerator::GetTokenId(Object* token) { | |
| 62 Isolate* isolate = Isolate::Current(); | |
| 63 if (token == NULL) return TokenEnumerator::kNoSecurityToken; | |
| 64 for (int i = 0; i < token_locations_.length(); ++i) { | |
| 65 if (*token_locations_[i] == token && !token_removed_[i]) return i; | |
| 66 } | |
| 67 Handle<Object> handle = isolate->global_handles()->Create(token); | |
| 68 // handle.location() points to a memory cell holding a pointer | |
| 69 // to a token object in the V8's heap. | |
| 70 isolate->global_handles()->MakeWeak(handle.location(), | |
| 71 this, | |
| 72 TokenRemovedCallback); | |
| 73 token_locations_.Add(handle.location()); | |
| 74 token_removed_.Add(false); | |
| 75 return token_locations_.length() - 1; | |
| 76 } | |
| 77 | |
| 78 | |
| 79 void TokenEnumerator::TokenRemovedCallback(v8::Isolate* isolate, | |
| 80 v8::Persistent<v8::Value>* handle, | |
| 81 void* parameter) { | |
| 82 reinterpret_cast<TokenEnumerator*>(parameter)->TokenRemoved( | |
| 83 Utils::OpenPersistent(handle).location()); | |
| 84 handle->Dispose(isolate); | |
| 85 } | |
| 86 | |
| 87 | |
| 88 void TokenEnumerator::TokenRemoved(Object** token_location) { | |
| 89 for (int i = 0; i < token_locations_.length(); ++i) { | |
| 90 if (token_locations_[i] == token_location && !token_removed_[i]) { | |
| 91 token_removed_[i] = true; | |
| 92 return; | |
| 93 } | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 | |
| 98 StringsStorage::StringsStorage() | 44 StringsStorage::StringsStorage() |
| 99 : names_(StringsMatch) { | 45 : names_(StringsMatch) { |
| 100 } | 46 } |
| 101 | 47 |
| 102 | 48 |
| 103 StringsStorage::~StringsStorage() { | 49 StringsStorage::~StringsStorage() { |
| 104 for (HashMap::Entry* p = names_.Start(); | 50 for (HashMap::Entry* p = names_.Start(); |
| 105 p != NULL; | 51 p != NULL; |
| 106 p = names_.Next(p)) { | 52 p = names_.Next(p)) { |
| 107 DeleteArray(reinterpret_cast<const char*>(p->value)); | 53 DeleteArray(reinterpret_cast<const char*>(p->value)); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 return tree_->TicksToMillis(self_ticks_); | 213 return tree_->TicksToMillis(self_ticks_); |
| 268 } | 214 } |
| 269 | 215 |
| 270 | 216 |
| 271 double ProfileNode::GetTotalMillis() const { | 217 double ProfileNode::GetTotalMillis() const { |
| 272 return tree_->TicksToMillis(total_ticks_); | 218 return tree_->TicksToMillis(total_ticks_); |
| 273 } | 219 } |
| 274 | 220 |
| 275 | 221 |
| 276 void ProfileNode::Print(int indent) { | 222 void ProfileNode::Print(int indent) { |
| 277 OS::Print("%5u %5u %*c %s%s [%d] #%d %d", | 223 OS::Print("%5u %5u %*c %s%s #%d %d", |
| 278 total_ticks_, self_ticks_, | 224 total_ticks_, self_ticks_, |
| 279 indent, ' ', | 225 indent, ' ', |
| 280 entry_->name_prefix(), | 226 entry_->name_prefix(), |
| 281 entry_->name(), | 227 entry_->name(), |
| 282 entry_->security_token_id(), | |
| 283 entry_->script_id(), | 228 entry_->script_id(), |
| 284 id()); | 229 id()); |
| 285 if (entry_->resource_name()[0] != '\0') | 230 if (entry_->resource_name()[0] != '\0') |
| 286 OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number()); | 231 OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number()); |
| 287 OS::Print("\n"); | 232 OS::Print("\n"); |
| 288 for (HashMap::Entry* p = children_.Start(); | 233 for (HashMap::Entry* p = children_.Start(); |
| 289 p != NULL; | 234 p != NULL; |
| 290 p = children_.Next(p)) { | 235 p = children_.Next(p)) { |
| 291 reinterpret_cast<ProfileNode*>(p->value)->Print(indent + 2); | 236 reinterpret_cast<ProfileNode*>(p->value)->Print(indent + 2); |
| 292 } | 237 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 | 291 |
| 347 | 292 |
| 348 struct NodesPair { | 293 struct NodesPair { |
| 349 NodesPair(ProfileNode* src, ProfileNode* dst) | 294 NodesPair(ProfileNode* src, ProfileNode* dst) |
| 350 : src(src), dst(dst) { } | 295 : src(src), dst(dst) { } |
| 351 ProfileNode* src; | 296 ProfileNode* src; |
| 352 ProfileNode* dst; | 297 ProfileNode* dst; |
| 353 }; | 298 }; |
| 354 | 299 |
| 355 | 300 |
| 356 class FilteredCloneCallback { | |
| 357 public: | |
| 358 FilteredCloneCallback(ProfileNode* dst_root, int security_token_id) | |
| 359 : stack_(10), | |
| 360 security_token_id_(security_token_id) { | |
| 361 stack_.Add(NodesPair(NULL, dst_root)); | |
| 362 } | |
| 363 | |
| 364 void BeforeTraversingChild(ProfileNode* parent, ProfileNode* child) { | |
| 365 if (IsTokenAcceptable(child->entry()->security_token_id(), | |
| 366 parent->entry()->security_token_id())) { | |
| 367 ProfileNode* clone = stack_.last().dst->FindOrAddChild(child->entry()); | |
| 368 clone->IncreaseSelfTicks(child->self_ticks()); | |
| 369 stack_.Add(NodesPair(child, clone)); | |
| 370 } else { | |
| 371 // Attribute ticks to parent node. | |
| 372 stack_.last().dst->IncreaseSelfTicks(child->self_ticks()); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 void AfterAllChildrenTraversed(ProfileNode* parent) { } | |
| 377 | |
| 378 void AfterChildTraversed(ProfileNode*, ProfileNode* child) { | |
| 379 if (stack_.last().src == child) { | |
| 380 stack_.RemoveLast(); | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 private: | |
| 385 bool IsTokenAcceptable(int token, int parent_token) { | |
| 386 if (token == TokenEnumerator::kNoSecurityToken | |
| 387 || token == security_token_id_) return true; | |
| 388 if (token == TokenEnumerator::kInheritsSecurityToken) { | |
| 389 ASSERT(parent_token != TokenEnumerator::kInheritsSecurityToken); | |
| 390 return parent_token == TokenEnumerator::kNoSecurityToken | |
| 391 || parent_token == security_token_id_; | |
| 392 } | |
| 393 return false; | |
| 394 } | |
| 395 | |
| 396 List<NodesPair> stack_; | |
| 397 int security_token_id_; | |
| 398 }; | |
| 399 | |
| 400 void ProfileTree::FilteredClone(ProfileTree* src, int security_token_id) { | |
| 401 ms_to_ticks_scale_ = src->ms_to_ticks_scale_; | |
| 402 FilteredCloneCallback cb(root_, security_token_id); | |
| 403 src->TraverseDepthFirst(&cb); | |
| 404 CalculateTotalTicks(); | |
| 405 } | |
| 406 | |
| 407 | |
| 408 void ProfileTree::SetTickRatePerMs(double ticks_per_ms) { | 301 void ProfileTree::SetTickRatePerMs(double ticks_per_ms) { |
| 409 ms_to_ticks_scale_ = ticks_per_ms > 0 ? 1.0 / ticks_per_ms : 1.0; | 302 ms_to_ticks_scale_ = ticks_per_ms > 0 ? 1.0 / ticks_per_ms : 1.0; |
| 410 } | 303 } |
| 411 | 304 |
| 412 | 305 |
| 413 class Position { | 306 class Position { |
| 414 public: | 307 public: |
| 415 explicit Position(ProfileNode* node) | 308 explicit Position(ProfileNode* node) |
| 416 : node(node), child_idx_(0) { } | 309 : node(node), child_idx_(0) { } |
| 417 INLINE(ProfileNode* current_child()) { | 310 INLINE(ProfileNode* current_child()) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 void CpuProfile::CalculateTotalTicks() { | 381 void CpuProfile::CalculateTotalTicks() { |
| 489 top_down_.CalculateTotalTicks(); | 382 top_down_.CalculateTotalTicks(); |
| 490 } | 383 } |
| 491 | 384 |
| 492 | 385 |
| 493 void CpuProfile::SetActualSamplingRate(double actual_sampling_rate) { | 386 void CpuProfile::SetActualSamplingRate(double actual_sampling_rate) { |
| 494 top_down_.SetTickRatePerMs(actual_sampling_rate); | 387 top_down_.SetTickRatePerMs(actual_sampling_rate); |
| 495 } | 388 } |
| 496 | 389 |
| 497 | 390 |
| 498 CpuProfile* CpuProfile::FilteredClone(int security_token_id) { | |
| 499 ASSERT(security_token_id != TokenEnumerator::kNoSecurityToken); | |
| 500 CpuProfile* clone = new CpuProfile(title_, uid_, false); | |
| 501 clone->top_down_.FilteredClone(&top_down_, security_token_id); | |
| 502 return clone; | |
| 503 } | |
| 504 | |
| 505 | |
| 506 void CpuProfile::ShortPrint() { | 391 void CpuProfile::ShortPrint() { |
| 507 OS::Print("top down "); | 392 OS::Print("top down "); |
| 508 top_down_.ShortPrint(); | 393 top_down_.ShortPrint(); |
| 509 } | 394 } |
| 510 | 395 |
| 511 | 396 |
| 512 void CpuProfile::Print() { | 397 void CpuProfile::Print() { |
| 513 OS::Print("[Top down]:\n"); | 398 OS::Print("[Top down]:\n"); |
| 514 top_down_.Print(); | 399 top_down_.Print(); |
| 515 } | 400 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 } | 479 } |
| 595 | 480 |
| 596 | 481 |
| 597 void CodeMap::Print() { | 482 void CodeMap::Print() { |
| 598 CodeTreePrinter printer; | 483 CodeTreePrinter printer; |
| 599 tree_.ForEach(&printer); | 484 tree_.ForEach(&printer); |
| 600 } | 485 } |
| 601 | 486 |
| 602 | 487 |
| 603 CpuProfilesCollection::CpuProfilesCollection() | 488 CpuProfilesCollection::CpuProfilesCollection() |
| 604 : profiles_uids_(UidsMatch), | 489 : current_profiles_semaphore_(OS::CreateSemaphore(1)) { |
| 605 current_profiles_semaphore_(OS::CreateSemaphore(1)) { | |
| 606 // Create list of unabridged profiles. | |
| 607 profiles_by_token_.Add(new List<CpuProfile*>()); | |
| 608 } | 490 } |
| 609 | 491 |
| 610 | 492 |
| 611 static void DeleteCodeEntry(CodeEntry** entry_ptr) { | 493 static void DeleteCodeEntry(CodeEntry** entry_ptr) { |
| 612 delete *entry_ptr; | 494 delete *entry_ptr; |
| 613 } | 495 } |
| 614 | 496 |
| 615 static void DeleteCpuProfile(CpuProfile** profile_ptr) { | 497 static void DeleteCpuProfile(CpuProfile** profile_ptr) { |
| 616 delete *profile_ptr; | 498 delete *profile_ptr; |
| 617 } | 499 } |
| 618 | 500 |
| 619 static void DeleteProfilesList(List<CpuProfile*>** list_ptr) { | |
| 620 if (*list_ptr != NULL) { | |
| 621 (*list_ptr)->Iterate(DeleteCpuProfile); | |
| 622 delete *list_ptr; | |
| 623 } | |
| 624 } | |
| 625 | |
| 626 CpuProfilesCollection::~CpuProfilesCollection() { | 501 CpuProfilesCollection::~CpuProfilesCollection() { |
| 627 delete current_profiles_semaphore_; | 502 delete current_profiles_semaphore_; |
| 503 finished_profiles_.Iterate(DeleteCpuProfile); |
| 628 current_profiles_.Iterate(DeleteCpuProfile); | 504 current_profiles_.Iterate(DeleteCpuProfile); |
| 629 detached_profiles_.Iterate(DeleteCpuProfile); | |
| 630 profiles_by_token_.Iterate(DeleteProfilesList); | |
| 631 code_entries_.Iterate(DeleteCodeEntry); | 505 code_entries_.Iterate(DeleteCodeEntry); |
| 632 } | 506 } |
| 633 | 507 |
| 634 | 508 |
| 635 bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid, | 509 bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid, |
| 636 bool record_samples) { | 510 bool record_samples) { |
| 637 ASSERT(uid > 0); | 511 ASSERT(uid > 0); |
| 638 current_profiles_semaphore_->Wait(); | 512 current_profiles_semaphore_->Wait(); |
| 639 if (current_profiles_.length() >= kMaxSimultaneousProfiles) { | 513 if (current_profiles_.length() >= kMaxSimultaneousProfiles) { |
| 640 current_profiles_semaphore_->Signal(); | 514 current_profiles_semaphore_->Signal(); |
| 641 return false; | 515 return false; |
| 642 } | 516 } |
| 643 for (int i = 0; i < current_profiles_.length(); ++i) { | 517 for (int i = 0; i < current_profiles_.length(); ++i) { |
| 644 if (strcmp(current_profiles_[i]->title(), title) == 0) { | 518 if (strcmp(current_profiles_[i]->title(), title) == 0) { |
| 645 // Ignore attempts to start profile with the same title. | 519 // Ignore attempts to start profile with the same title. |
| 646 current_profiles_semaphore_->Signal(); | 520 current_profiles_semaphore_->Signal(); |
| 647 return false; | 521 return false; |
| 648 } | 522 } |
| 649 } | 523 } |
| 650 current_profiles_.Add(new CpuProfile(title, uid, record_samples)); | 524 current_profiles_.Add(new CpuProfile(title, uid, record_samples)); |
| 651 current_profiles_semaphore_->Signal(); | 525 current_profiles_semaphore_->Signal(); |
| 652 return true; | 526 return true; |
| 653 } | 527 } |
| 654 | 528 |
| 655 | 529 |
| 656 CpuProfile* CpuProfilesCollection::StopProfiling(int security_token_id, | 530 CpuProfile* CpuProfilesCollection::StopProfiling(const char* title, |
| 657 const char* title, | |
| 658 double actual_sampling_rate) { | 531 double actual_sampling_rate) { |
| 659 const int title_len = StrLength(title); | 532 const int title_len = StrLength(title); |
| 660 CpuProfile* profile = NULL; | 533 CpuProfile* profile = NULL; |
| 661 current_profiles_semaphore_->Wait(); | 534 current_profiles_semaphore_->Wait(); |
| 662 for (int i = current_profiles_.length() - 1; i >= 0; --i) { | 535 for (int i = current_profiles_.length() - 1; i >= 0; --i) { |
| 663 if (title_len == 0 || strcmp(current_profiles_[i]->title(), title) == 0) { | 536 if (title_len == 0 || strcmp(current_profiles_[i]->title(), title) == 0) { |
| 664 profile = current_profiles_.Remove(i); | 537 profile = current_profiles_.Remove(i); |
| 665 break; | 538 break; |
| 666 } | 539 } |
| 667 } | 540 } |
| 668 current_profiles_semaphore_->Signal(); | 541 current_profiles_semaphore_->Signal(); |
| 669 | 542 |
| 670 if (profile != NULL) { | 543 if (profile == NULL) return NULL; |
| 671 profile->CalculateTotalTicks(); | 544 profile->CalculateTotalTicks(); |
| 672 profile->SetActualSamplingRate(actual_sampling_rate); | 545 profile->SetActualSamplingRate(actual_sampling_rate); |
| 673 List<CpuProfile*>* unabridged_list = | 546 finished_profiles_.Add(profile); |
| 674 profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)]; | 547 return profile; |
| 675 unabridged_list->Add(profile); | |
| 676 HashMap::Entry* entry = | |
| 677 profiles_uids_.Lookup(reinterpret_cast<void*>(profile->uid()), | |
| 678 static_cast<uint32_t>(profile->uid()), | |
| 679 true); | |
| 680 ASSERT(entry->value == NULL); | |
| 681 entry->value = reinterpret_cast<void*>(unabridged_list->length() - 1); | |
| 682 return GetProfile(security_token_id, profile->uid()); | |
| 683 } | |
| 684 return NULL; | |
| 685 } | 548 } |
| 686 | 549 |
| 687 | 550 |
| 688 CpuProfile* CpuProfilesCollection::GetProfile(int security_token_id, | |
| 689 unsigned uid) { | |
| 690 int index = GetProfileIndex(uid); | |
| 691 if (index < 0) return NULL; | |
| 692 List<CpuProfile*>* unabridged_list = | |
| 693 profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)]; | |
| 694 if (security_token_id == TokenEnumerator::kNoSecurityToken) { | |
| 695 return unabridged_list->at(index); | |
| 696 } | |
| 697 List<CpuProfile*>* list = GetProfilesList(security_token_id); | |
| 698 if (list->at(index) == NULL) { | |
| 699 (*list)[index] = | |
| 700 unabridged_list->at(index)->FilteredClone(security_token_id); | |
| 701 } | |
| 702 return list->at(index); | |
| 703 } | |
| 704 | |
| 705 | |
| 706 int CpuProfilesCollection::GetProfileIndex(unsigned uid) { | |
| 707 HashMap::Entry* entry = profiles_uids_.Lookup(reinterpret_cast<void*>(uid), | |
| 708 static_cast<uint32_t>(uid), | |
| 709 false); | |
| 710 return entry != NULL ? | |
| 711 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)) : -1; | |
| 712 } | |
| 713 | |
| 714 | |
| 715 bool CpuProfilesCollection::IsLastProfile(const char* title) { | 551 bool CpuProfilesCollection::IsLastProfile(const char* title) { |
| 716 // Called from VM thread, and only it can mutate the list, | 552 // Called from VM thread, and only it can mutate the list, |
| 717 // so no locking is needed here. | 553 // so no locking is needed here. |
| 718 if (current_profiles_.length() != 1) return false; | 554 if (current_profiles_.length() != 1) return false; |
| 719 return StrLength(title) == 0 | 555 return StrLength(title) == 0 |
| 720 || strcmp(current_profiles_[0]->title(), title) == 0; | 556 || strcmp(current_profiles_[0]->title(), title) == 0; |
| 721 } | 557 } |
| 722 | 558 |
| 723 | 559 |
| 724 void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) { | 560 void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) { |
| 725 // Called from VM thread for a completed profile. | 561 // Called from VM thread for a completed profile. |
| 726 unsigned uid = profile->uid(); | 562 unsigned uid = profile->uid(); |
| 727 int index = GetProfileIndex(uid); | 563 for (int i = 0; i < finished_profiles_.length(); i++) { |
| 728 if (index < 0) { | 564 if (uid == finished_profiles_[i]->uid()) { |
| 729 detached_profiles_.RemoveElement(profile); | 565 finished_profiles_.Remove(i); |
| 730 return; | 566 return; |
| 731 } | |
| 732 profiles_uids_.Remove(reinterpret_cast<void*>(uid), | |
| 733 static_cast<uint32_t>(uid)); | |
| 734 // Decrement all indexes above the deleted one. | |
| 735 for (HashMap::Entry* p = profiles_uids_.Start(); | |
| 736 p != NULL; | |
| 737 p = profiles_uids_.Next(p)) { | |
| 738 intptr_t p_index = reinterpret_cast<intptr_t>(p->value); | |
| 739 if (p_index > index) { | |
| 740 p->value = reinterpret_cast<void*>(p_index - 1); | |
| 741 } | 567 } |
| 742 } | 568 } |
| 743 for (int i = 0; i < profiles_by_token_.length(); ++i) { | 569 UNREACHABLE(); |
| 744 List<CpuProfile*>* list = profiles_by_token_[i]; | |
| 745 if (list != NULL && index < list->length()) { | |
| 746 // Move all filtered clones into detached_profiles_, | |
| 747 // so we can know that they are still in use. | |
| 748 CpuProfile* cloned_profile = list->Remove(index); | |
| 749 if (cloned_profile != NULL && cloned_profile != profile) { | |
| 750 detached_profiles_.Add(cloned_profile); | |
| 751 } | |
| 752 } | |
| 753 } | |
| 754 } | 570 } |
| 755 | 571 |
| 756 | 572 |
| 757 int CpuProfilesCollection::TokenToIndex(int security_token_id) { | |
| 758 ASSERT(TokenEnumerator::kNoSecurityToken == -1); | |
| 759 return security_token_id + 1; // kNoSecurityToken -> 0, 0 -> 1, ... | |
| 760 } | |
| 761 | |
| 762 | |
| 763 List<CpuProfile*>* CpuProfilesCollection::GetProfilesList( | |
| 764 int security_token_id) { | |
| 765 const int index = TokenToIndex(security_token_id); | |
| 766 const int lists_to_add = index - profiles_by_token_.length() + 1; | |
| 767 if (lists_to_add > 0) profiles_by_token_.AddBlock(NULL, lists_to_add); | |
| 768 List<CpuProfile*>* unabridged_list = | |
| 769 profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)]; | |
| 770 const int current_count = unabridged_list->length(); | |
| 771 if (profiles_by_token_[index] == NULL) { | |
| 772 profiles_by_token_[index] = new List<CpuProfile*>(current_count); | |
| 773 } | |
| 774 List<CpuProfile*>* list = profiles_by_token_[index]; | |
| 775 const int profiles_to_add = current_count - list->length(); | |
| 776 if (profiles_to_add > 0) list->AddBlock(NULL, profiles_to_add); | |
| 777 return list; | |
| 778 } | |
| 779 | |
| 780 | |
| 781 List<CpuProfile*>* CpuProfilesCollection::Profiles(int security_token_id) { | |
| 782 List<CpuProfile*>* unabridged_list = | |
| 783 profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)]; | |
| 784 if (security_token_id == TokenEnumerator::kNoSecurityToken) { | |
| 785 return unabridged_list; | |
| 786 } | |
| 787 List<CpuProfile*>* list = GetProfilesList(security_token_id); | |
| 788 const int current_count = unabridged_list->length(); | |
| 789 for (int i = 0; i < current_count; ++i) { | |
| 790 if (list->at(i) == NULL) { | |
| 791 (*list)[i] = unabridged_list->at(i)->FilteredClone(security_token_id); | |
| 792 } | |
| 793 } | |
| 794 return list; | |
| 795 } | |
| 796 | |
| 797 | |
| 798 void CpuProfilesCollection::AddPathToCurrentProfiles( | 573 void CpuProfilesCollection::AddPathToCurrentProfiles( |
| 799 const Vector<CodeEntry*>& path) { | 574 const Vector<CodeEntry*>& path) { |
| 800 // As starting / stopping profiles is rare relatively to this | 575 // As starting / stopping profiles is rare relatively to this |
| 801 // method, we don't bother minimizing the duration of lock holding, | 576 // method, we don't bother minimizing the duration of lock holding, |
| 802 // e.g. copying contents of the list to a local vector. | 577 // e.g. copying contents of the list to a local vector. |
| 803 current_profiles_semaphore_->Wait(); | 578 current_profiles_semaphore_->Wait(); |
| 804 for (int i = 0; i < current_profiles_.length(); ++i) { | 579 for (int i = 0; i < current_profiles_.length(); ++i) { |
| 805 current_profiles_[i]->AddPath(path); | 580 current_profiles_[i]->AddPath(path); |
| 806 } | 581 } |
| 807 current_profiles_semaphore_->Signal(); | 582 current_profiles_semaphore_->Signal(); |
| 808 } | 583 } |
| 809 | 584 |
| 810 | 585 |
| 811 CodeEntry* CpuProfilesCollection::NewCodeEntry( | 586 CodeEntry* CpuProfilesCollection::NewCodeEntry( |
| 812 Logger::LogEventsAndTags tag, | 587 Logger::LogEventsAndTags tag, |
| 813 const char* name, | 588 const char* name, |
| 814 int security_token_id, | |
| 815 const char* name_prefix, | 589 const char* name_prefix, |
| 816 const char* resource_name, | 590 const char* resource_name, |
| 817 int line_number) { | 591 int line_number) { |
| 818 CodeEntry* code_entry = new CodeEntry(tag, | 592 CodeEntry* code_entry = new CodeEntry(tag, |
| 819 name, | 593 name, |
| 820 security_token_id, | |
| 821 name_prefix, | 594 name_prefix, |
| 822 resource_name, | 595 resource_name, |
| 823 line_number); | 596 line_number); |
| 824 code_entries_.Add(code_entry); | 597 code_entries_.Add(code_entry); |
| 825 return code_entry; | 598 return code_entry; |
| 826 } | 599 } |
| 827 | 600 |
| 828 | 601 |
| 829 void SampleRateCalculator::Tick() { | 602 void SampleRateCalculator::Tick() { |
| 830 if (--wall_time_query_countdown_ == 0) | 603 if (--wall_time_query_countdown_ == 0) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 if (no_symbolized_entries) { | 714 if (no_symbolized_entries) { |
| 942 *entry++ = EntryForVMState(sample.state); | 715 *entry++ = EntryForVMState(sample.state); |
| 943 } | 716 } |
| 944 } | 717 } |
| 945 | 718 |
| 946 profiles_->AddPathToCurrentProfiles(entries); | 719 profiles_->AddPathToCurrentProfiles(entries); |
| 947 } | 720 } |
| 948 | 721 |
| 949 | 722 |
| 950 } } // namespace v8::internal | 723 } } // namespace v8::internal |
| OLD | NEW |