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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 const HashMap& local_pretenuring_feedback) { | 511 const HashMap& local_pretenuring_feedback) { |
512 AllocationSite* site = nullptr; | 512 AllocationSite* site = nullptr; |
513 for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start(); | 513 for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start(); |
514 local_entry != nullptr; | 514 local_entry != nullptr; |
515 local_entry = local_pretenuring_feedback.Next(local_entry)) { | 515 local_entry = local_pretenuring_feedback.Next(local_entry)) { |
516 site = reinterpret_cast<AllocationSite*>(local_entry->key); | 516 site = reinterpret_cast<AllocationSite*>(local_entry->key); |
517 MapWord map_word = site->map_word(); | 517 MapWord map_word = site->map_word(); |
518 if (map_word.IsForwardingAddress()) { | 518 if (map_word.IsForwardingAddress()) { |
519 site = AllocationSite::cast(map_word.ToForwardingAddress()); | 519 site = AllocationSite::cast(map_word.ToForwardingAddress()); |
520 } | 520 } |
521 DCHECK(site->IsAllocationSite()); | 521 |
| 522 // We have not validated the allocation site yet, since we have not |
| 523 // dereferenced the site during collecting information. |
| 524 // This is an inlined check of AllocationMemento::IsValid. |
| 525 if (!site->IsAllocationSite() || site->IsZombie()) continue; |
| 526 |
522 int value = | 527 int value = |
523 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value)); | 528 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value)); |
524 DCHECK_GT(value, 0); | 529 DCHECK_GT(value, 0); |
525 | 530 |
526 { | 531 if (site->IncrementMementoFoundCount(value)) { |
527 // TODO(mlippautz): For parallel processing we need synchronization here. | 532 global_pretenuring_feedback_->LookupOrInsert(site, |
528 if (site->IncrementMementoFoundCount(value)) { | 533 ObjectHash(site->address())); |
529 global_pretenuring_feedback_->LookupOrInsert( | |
530 site, static_cast<uint32_t>(bit_cast<uintptr_t>(site))); | |
531 } | |
532 } | 534 } |
533 } | 535 } |
534 } | 536 } |
535 | 537 |
536 | 538 |
537 class Heap::PretenuringScope { | 539 class Heap::PretenuringScope { |
538 public: | 540 public: |
539 explicit PretenuringScope(Heap* heap) : heap_(heap) { | 541 explicit PretenuringScope(Heap* heap) : heap_(heap) { |
540 heap_->global_pretenuring_feedback_ = | 542 heap_->global_pretenuring_feedback_ = |
541 new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity); | 543 new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity); |
(...skipping 17 matching lines...) Expand all Loading... |
559 int allocation_mementos_found = 0; | 561 int allocation_mementos_found = 0; |
560 int allocation_sites = 0; | 562 int allocation_sites = 0; |
561 int active_allocation_sites = 0; | 563 int active_allocation_sites = 0; |
562 | 564 |
563 AllocationSite* site = nullptr; | 565 AllocationSite* site = nullptr; |
564 | 566 |
565 // Step 1: Digest feedback for recorded allocation sites. | 567 // Step 1: Digest feedback for recorded allocation sites. |
566 bool maximum_size_scavenge = MaximumSizeScavenge(); | 568 bool maximum_size_scavenge = MaximumSizeScavenge(); |
567 for (HashMap::Entry* e = global_pretenuring_feedback_->Start(); | 569 for (HashMap::Entry* e = global_pretenuring_feedback_->Start(); |
568 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { | 570 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { |
| 571 allocation_sites++; |
569 site = reinterpret_cast<AllocationSite*>(e->key); | 572 site = reinterpret_cast<AllocationSite*>(e->key); |
570 int found_count = site->memento_found_count(); | 573 int found_count = site->memento_found_count(); |
571 // The fact that we have an entry in the storage means that we've found | 574 // An entry in the storage does not imply that the count is > 0 because |
572 // the site at least once. | 575 // allocation sites might have been reset due to too many objects dying |
573 DCHECK_GT(found_count, 0); | 576 // in old space. |
574 DCHECK(site->IsAllocationSite()); | 577 if (found_count > 0) { |
575 allocation_sites++; | 578 DCHECK(site->IsAllocationSite()); |
576 active_allocation_sites++; | 579 active_allocation_sites++; |
577 allocation_mementos_found += found_count; | 580 allocation_mementos_found += found_count; |
578 if (site->DigestPretenuringFeedback(maximum_size_scavenge)) { | 581 if (site->DigestPretenuringFeedback(maximum_size_scavenge)) { |
579 trigger_deoptimization = true; | 582 trigger_deoptimization = true; |
580 } | 583 } |
581 if (site->GetPretenureMode() == TENURED) { | 584 if (site->GetPretenureMode() == TENURED) { |
582 tenure_decisions++; | 585 tenure_decisions++; |
583 } else { | 586 } else { |
584 dont_tenure_decisions++; | 587 dont_tenure_decisions++; |
| 588 } |
585 } | 589 } |
586 } | 590 } |
587 | 591 |
588 // Step 2: Deopt maybe tenured allocation sites if necessary. | 592 // Step 2: Deopt maybe tenured allocation sites if necessary. |
589 bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites(); | 593 bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites(); |
590 if (deopt_maybe_tenured) { | 594 if (deopt_maybe_tenured) { |
591 Object* list_element = allocation_sites_list(); | 595 Object* list_element = allocation_sites_list(); |
592 while (list_element->IsAllocationSite()) { | 596 while (list_element->IsAllocationSite()) { |
593 site = AllocationSite::cast(list_element); | 597 site = AllocationSite::cast(list_element); |
594 DCHECK(site->IsAllocationSite()); | 598 DCHECK(site->IsAllocationSite()); |
(...skipping 5623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6218 } | 6222 } |
6219 | 6223 |
6220 | 6224 |
6221 // static | 6225 // static |
6222 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6226 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6223 return StaticVisitorBase::GetVisitorId(map); | 6227 return StaticVisitorBase::GetVisitorId(map); |
6224 } | 6228 } |
6225 | 6229 |
6226 } // namespace internal | 6230 } // namespace internal |
6227 } // namespace v8 | 6231 } // namespace v8 |
OLD | NEW |