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/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 495 |
496 | 496 |
497 void Heap::RepairFreeListsAfterDeserialization() { | 497 void Heap::RepairFreeListsAfterDeserialization() { |
498 PagedSpaces spaces(this); | 498 PagedSpaces spaces(this); |
499 for (PagedSpace* space = spaces.next(); space != NULL; | 499 for (PagedSpace* space = spaces.next(); space != NULL; |
500 space = spaces.next()) { | 500 space = spaces.next()) { |
501 space->RepairFreeListsAfterDeserialization(); | 501 space->RepairFreeListsAfterDeserialization(); |
502 } | 502 } |
503 } | 503 } |
504 | 504 |
505 | |
506 void Heap::MergeAllocationSitePretenuringFeedback( | 505 void Heap::MergeAllocationSitePretenuringFeedback( |
507 const HashMap& local_pretenuring_feedback) { | 506 const base::HashMap& local_pretenuring_feedback) { |
508 AllocationSite* site = nullptr; | 507 AllocationSite* site = nullptr; |
509 for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start(); | 508 for (base::HashMap::Entry* local_entry = local_pretenuring_feedback.Start(); |
510 local_entry != nullptr; | 509 local_entry != nullptr; |
511 local_entry = local_pretenuring_feedback.Next(local_entry)) { | 510 local_entry = local_pretenuring_feedback.Next(local_entry)) { |
512 site = reinterpret_cast<AllocationSite*>(local_entry->key); | 511 site = reinterpret_cast<AllocationSite*>(local_entry->key); |
513 MapWord map_word = site->map_word(); | 512 MapWord map_word = site->map_word(); |
514 if (map_word.IsForwardingAddress()) { | 513 if (map_word.IsForwardingAddress()) { |
515 site = AllocationSite::cast(map_word.ToForwardingAddress()); | 514 site = AllocationSite::cast(map_word.ToForwardingAddress()); |
516 } | 515 } |
517 | 516 |
518 // We have not validated the allocation site yet, since we have not | 517 // We have not validated the allocation site yet, since we have not |
519 // dereferenced the site during collecting information. | 518 // dereferenced the site during collecting information. |
520 // This is an inlined check of AllocationMemento::IsValid. | 519 // This is an inlined check of AllocationMemento::IsValid. |
521 if (!site->IsAllocationSite() || site->IsZombie()) continue; | 520 if (!site->IsAllocationSite() || site->IsZombie()) continue; |
522 | 521 |
523 int value = | 522 int value = |
524 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value)); | 523 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value)); |
525 DCHECK_GT(value, 0); | 524 DCHECK_GT(value, 0); |
526 | 525 |
527 if (site->IncrementMementoFoundCount(value)) { | 526 if (site->IncrementMementoFoundCount(value)) { |
528 global_pretenuring_feedback_->LookupOrInsert(site, | 527 global_pretenuring_feedback_->LookupOrInsert(site, |
529 ObjectHash(site->address())); | 528 ObjectHash(site->address())); |
530 } | 529 } |
531 } | 530 } |
532 } | 531 } |
533 | 532 |
534 | 533 |
535 class Heap::PretenuringScope { | 534 class Heap::PretenuringScope { |
536 public: | 535 public: |
537 explicit PretenuringScope(Heap* heap) : heap_(heap) { | 536 explicit PretenuringScope(Heap* heap) : heap_(heap) { |
538 heap_->global_pretenuring_feedback_ = | 537 heap_->global_pretenuring_feedback_ = new base::HashMap( |
539 new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity); | 538 base::HashMap::PointersMatch, kInitialFeedbackCapacity); |
540 } | 539 } |
541 | 540 |
542 ~PretenuringScope() { | 541 ~PretenuringScope() { |
543 delete heap_->global_pretenuring_feedback_; | 542 delete heap_->global_pretenuring_feedback_; |
544 heap_->global_pretenuring_feedback_ = nullptr; | 543 heap_->global_pretenuring_feedback_ = nullptr; |
545 } | 544 } |
546 | 545 |
547 private: | 546 private: |
548 Heap* heap_; | 547 Heap* heap_; |
549 }; | 548 }; |
550 | 549 |
551 | 550 |
552 void Heap::ProcessPretenuringFeedback() { | 551 void Heap::ProcessPretenuringFeedback() { |
553 bool trigger_deoptimization = false; | 552 bool trigger_deoptimization = false; |
554 if (FLAG_allocation_site_pretenuring) { | 553 if (FLAG_allocation_site_pretenuring) { |
555 int tenure_decisions = 0; | 554 int tenure_decisions = 0; |
556 int dont_tenure_decisions = 0; | 555 int dont_tenure_decisions = 0; |
557 int allocation_mementos_found = 0; | 556 int allocation_mementos_found = 0; |
558 int allocation_sites = 0; | 557 int allocation_sites = 0; |
559 int active_allocation_sites = 0; | 558 int active_allocation_sites = 0; |
560 | 559 |
561 AllocationSite* site = nullptr; | 560 AllocationSite* site = nullptr; |
562 | 561 |
563 // Step 1: Digest feedback for recorded allocation sites. | 562 // Step 1: Digest feedback for recorded allocation sites. |
564 bool maximum_size_scavenge = MaximumSizeScavenge(); | 563 bool maximum_size_scavenge = MaximumSizeScavenge(); |
565 for (HashMap::Entry* e = global_pretenuring_feedback_->Start(); | 564 for (base::HashMap::Entry* e = global_pretenuring_feedback_->Start(); |
566 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { | 565 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { |
567 allocation_sites++; | 566 allocation_sites++; |
568 site = reinterpret_cast<AllocationSite*>(e->key); | 567 site = reinterpret_cast<AllocationSite*>(e->key); |
569 int found_count = site->memento_found_count(); | 568 int found_count = site->memento_found_count(); |
570 // An entry in the storage does not imply that the count is > 0 because | 569 // An entry in the storage does not imply that the count is > 0 because |
571 // allocation sites might have been reset due to too many objects dying | 570 // allocation sites might have been reset due to too many objects dying |
572 // in old space. | 571 // in old space. |
573 if (found_count > 0) { | 572 if (found_count > 0) { |
574 DCHECK(site->IsAllocationSite()); | 573 DCHECK(site->IsAllocationSite()); |
575 active_allocation_sites++; | 574 active_allocation_sites++; |
(...skipping 5815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6391 } | 6390 } |
6392 | 6391 |
6393 | 6392 |
6394 // static | 6393 // static |
6395 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6394 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6396 return StaticVisitorBase::GetVisitorId(map); | 6395 return StaticVisitorBase::GetVisitorId(map); |
6397 } | 6396 } |
6398 | 6397 |
6399 } // namespace internal | 6398 } // namespace internal |
6400 } // namespace v8 | 6399 } // namespace v8 |
OLD | NEW |