Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: src/heap/heap.cc

Issue 1577853007: [heap] Parallel newspace evacuation, semispace copy, and compaction \o/ (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Various non-functional changes Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 gc_count_++; 430 gc_count_++;
431 431
432 #ifdef VERIFY_HEAP 432 #ifdef VERIFY_HEAP
433 if (FLAG_verify_heap) { 433 if (FLAG_verify_heap) {
434 Verify(); 434 Verify();
435 } 435 }
436 #endif 436 #endif
437 } 437 }
438 438
439 // Reset GC statistics. 439 // Reset GC statistics.
440 promoted_objects_size_ = 0; 440 promoted_objects_size_.SetValue(0);
441 previous_semi_space_copied_object_size_ = semi_space_copied_object_size_; 441 previous_semi_space_copied_object_size_ = semi_space_copied_object_size();
442 semi_space_copied_object_size_ = 0; 442 semi_space_copied_object_size_.SetValue(0);
443 nodes_died_in_new_space_ = 0; 443 nodes_died_in_new_space_ = 0;
444 nodes_copied_in_new_space_ = 0; 444 nodes_copied_in_new_space_ = 0;
445 nodes_promoted_ = 0; 445 nodes_promoted_ = 0;
446 446
447 UpdateMaximumCommitted(); 447 UpdateMaximumCommitted();
448 448
449 #ifdef DEBUG 449 #ifdef DEBUG
450 DCHECK(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC); 450 DCHECK(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
451 451
452 if (FLAG_gc_verbose) Print(); 452 if (FLAG_gc_verbose) Print();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 const HashMap& local_pretenuring_feedback) { 512 const HashMap& local_pretenuring_feedback) {
513 AllocationSite* site = nullptr; 513 AllocationSite* site = nullptr;
514 for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start(); 514 for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start();
515 local_entry != nullptr; 515 local_entry != nullptr;
516 local_entry = local_pretenuring_feedback.Next(local_entry)) { 516 local_entry = local_pretenuring_feedback.Next(local_entry)) {
517 site = reinterpret_cast<AllocationSite*>(local_entry->key); 517 site = reinterpret_cast<AllocationSite*>(local_entry->key);
518 MapWord map_word = site->map_word(); 518 MapWord map_word = site->map_word();
519 if (map_word.IsForwardingAddress()) { 519 if (map_word.IsForwardingAddress()) {
520 site = AllocationSite::cast(map_word.ToForwardingAddress()); 520 site = AllocationSite::cast(map_word.ToForwardingAddress());
521 } 521 }
522 DCHECK(site->IsAllocationSite()); 522
523 // We have not validated the allocation site yet, since we have not
524 // dereferenced the site during collecting information.
525 // This is an inlined check of AllocationMemento::IsValid.
526 if (!site->IsAllocationSite() || site->IsZombie()) continue;
527
523 int value = 528 int value =
524 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value)); 529 static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value));
525 DCHECK_GT(value, 0); 530 DCHECK_GT(value, 0);
526 531
527 { 532 if (site->IncrementMementoFoundCount(value)) {
528 // TODO(mlippautz): For parallel processing we need synchronization here. 533 global_pretenuring_feedback_->LookupOrInsert(
529 if (site->IncrementMementoFoundCount(value)) { 534 site, static_cast<uint32_t>(bit_cast<uintptr_t>(site)));
530 global_pretenuring_feedback_->LookupOrInsert(
531 site, static_cast<uint32_t>(bit_cast<uintptr_t>(site)));
532 }
533 } 535 }
534 } 536 }
535 } 537 }
536 538
537 539
538 class Heap::PretenuringScope { 540 class Heap::PretenuringScope {
539 public: 541 public:
540 explicit PretenuringScope(Heap* heap) : heap_(heap) { 542 explicit PretenuringScope(Heap* heap) : heap_(heap) {
541 heap_->global_pretenuring_feedback_ = 543 heap_->global_pretenuring_feedback_ =
542 new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity); 544 new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity);
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 NormalizedMapCache::cast(cache)->Clear(); 1229 NormalizedMapCache::cast(cache)->Clear();
1228 } 1230 }
1229 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); 1231 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
1230 } 1232 }
1231 } 1233 }
1232 1234
1233 1235
1234 void Heap::UpdateSurvivalStatistics(int start_new_space_size) { 1236 void Heap::UpdateSurvivalStatistics(int start_new_space_size) {
1235 if (start_new_space_size == 0) return; 1237 if (start_new_space_size == 0) return;
1236 1238
1237 promotion_ratio_ = (static_cast<double>(promoted_objects_size_) / 1239 promotion_ratio_ = (static_cast<double>(promoted_objects_size()) /
1238 static_cast<double>(start_new_space_size) * 100); 1240 static_cast<double>(start_new_space_size) * 100);
1239 1241
1240 if (previous_semi_space_copied_object_size_ > 0) { 1242 if (previous_semi_space_copied_object_size_ > 0) {
1241 promotion_rate_ = 1243 promotion_rate_ =
1242 (static_cast<double>(promoted_objects_size_) / 1244 (static_cast<double>(promoted_objects_size()) /
1243 static_cast<double>(previous_semi_space_copied_object_size_) * 100); 1245 static_cast<double>(previous_semi_space_copied_object_size_) * 100);
1244 } else { 1246 } else {
1245 promotion_rate_ = 0; 1247 promotion_rate_ = 0;
1246 } 1248 }
1247 1249
1248 semi_space_copied_rate_ = 1250 semi_space_copied_rate_ =
1249 (static_cast<double>(semi_space_copied_object_size_) / 1251 (static_cast<double>(semi_space_copied_object_size()) /
1250 static_cast<double>(start_new_space_size) * 100); 1252 static_cast<double>(start_new_space_size) * 100);
1251 1253
1252 double survival_rate = promotion_ratio_ + semi_space_copied_rate_; 1254 double survival_rate = promotion_ratio_ + semi_space_copied_rate_;
1253 tracer()->AddSurvivalRatio(survival_rate); 1255 tracer()->AddSurvivalRatio(survival_rate);
1254 if (survival_rate > kYoungSurvivalRateHighThreshold) { 1256 if (survival_rate > kYoungSurvivalRateHighThreshold) {
1255 high_survival_rate_period_length_++; 1257 high_survival_rate_period_length_++;
1256 } else { 1258 } else {
1257 high_survival_rate_period_length_ = 0; 1259 high_survival_rate_period_length_ = 0;
1258 } 1260 }
1259 } 1261 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 1304
1303 if (collector == MARK_COMPACTOR) { 1305 if (collector == MARK_COMPACTOR) {
1304 UpdateOldGenerationAllocationCounter(); 1306 UpdateOldGenerationAllocationCounter();
1305 // Perform mark-sweep with optional compaction. 1307 // Perform mark-sweep with optional compaction.
1306 MarkCompact(); 1308 MarkCompact();
1307 old_gen_exhausted_ = false; 1309 old_gen_exhausted_ = false;
1308 old_generation_size_configured_ = true; 1310 old_generation_size_configured_ = true;
1309 // This should be updated before PostGarbageCollectionProcessing, which 1311 // This should be updated before PostGarbageCollectionProcessing, which
1310 // can cause another GC. Take into account the objects promoted during GC. 1312 // can cause another GC. Take into account the objects promoted during GC.
1311 old_generation_allocation_counter_ += 1313 old_generation_allocation_counter_ +=
1312 static_cast<size_t>(promoted_objects_size_); 1314 static_cast<size_t>(promoted_objects_size());
1313 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); 1315 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
1314 } else { 1316 } else {
1315 Scavenge(); 1317 Scavenge();
1316 } 1318 }
1317 1319
1318 ProcessPretenuringFeedback(); 1320 ProcessPretenuringFeedback();
1319 } 1321 }
1320 1322
1321 UpdateSurvivalStatistics(start_new_space_size); 1323 UpdateSurvivalStatistics(start_new_space_size);
1322 ConfigureInitialOldGenerationSize(); 1324 ConfigureInitialOldGenerationSize();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 for (HeapObject* object = code_it.Next(); object != NULL; 1508 for (HeapObject* object = code_it.Next(); object != NULL;
1507 object = code_it.Next()) 1509 object = code_it.Next())
1508 object->Iterate(&v); 1510 object->Iterate(&v);
1509 } 1511 }
1510 #endif // VERIFY_HEAP 1512 #endif // VERIFY_HEAP
1511 1513
1512 1514
1513 void Heap::CheckNewSpaceExpansionCriteria() { 1515 void Heap::CheckNewSpaceExpansionCriteria() {
1514 if (FLAG_experimental_new_space_growth_heuristic) { 1516 if (FLAG_experimental_new_space_growth_heuristic) {
1515 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && 1517 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1516 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { 1518 survived_last_scavenge() * 100 / new_space_.TotalCapacity() >= 10) {
1517 // Grow the size of new space if there is room to grow, and more than 10% 1519 // Grow the size of new space if there is room to grow, and more than 10%
1518 // have survived the last scavenge. 1520 // have survived the last scavenge.
1519 new_space_.Grow(); 1521 new_space_.Grow();
1520 survived_since_last_expansion_ = 0; 1522 survived_since_last_expansion_.SetValue(0);
1521 } 1523 }
1522 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && 1524 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1523 survived_since_last_expansion_ > new_space_.TotalCapacity()) { 1525 survived_since_last_expansion() > new_space_.TotalCapacity()) {
1524 // Grow the size of new space if there is room to grow, and enough data 1526 // Grow the size of new space if there is room to grow, and enough data
1525 // has survived scavenge since the last expansion. 1527 // has survived scavenge since the last expansion.
1526 new_space_.Grow(); 1528 new_space_.Grow();
1527 survived_since_last_expansion_ = 0; 1529 survived_since_last_expansion_.SetValue(0);
1528 } 1530 }
1529 } 1531 }
1530 1532
1531 1533
1532 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { 1534 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1533 return heap->InNewSpace(*p) && 1535 return heap->InNewSpace(*p) &&
1534 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); 1536 !HeapObject::cast(*p)->map_word().IsForwardingAddress();
1535 } 1537 }
1536 1538
1537 1539
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 ProcessYoungWeakReferences(&weak_object_retainer); 1756 ProcessYoungWeakReferences(&weak_object_retainer);
1755 1757
1756 DCHECK(new_space_front == new_space_.top()); 1758 DCHECK(new_space_front == new_space_.top());
1757 1759
1758 // Set age mark. 1760 // Set age mark.
1759 new_space_.set_age_mark(new_space_.top()); 1761 new_space_.set_age_mark(new_space_.top());
1760 1762
1761 array_buffer_tracker()->FreeDead(true); 1763 array_buffer_tracker()->FreeDead(true);
1762 1764
1763 // Update how much has survived scavenge. 1765 // Update how much has survived scavenge.
1764 IncrementYoungSurvivorsCounter(static_cast<int>( 1766 IncrementYoungSurvivorsCounter(
1765 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); 1767 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size());
1766 1768
1767 LOG(isolate_, ResourceEvent("scavenge", "end")); 1769 LOG(isolate_, ResourceEvent("scavenge", "end"));
1768 1770
1769 gc_state_ = NOT_IN_GC; 1771 gc_state_ = NOT_IN_GC;
1770 } 1772 }
1771 1773
1772 1774
1773 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, 1775 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1774 Object** p) { 1776 Object** p) {
1775 MapWord first_word = HeapObject::cast(*p)->map_word(); 1777 MapWord first_word = HeapObject::cast(*p)->map_word();
(...skipping 4461 matching lines...) Expand 10 before | Expand all | Expand 10 after
6237 } 6239 }
6238 6240
6239 6241
6240 // static 6242 // static
6241 int Heap::GetStaticVisitorIdForMap(Map* map) { 6243 int Heap::GetStaticVisitorIdForMap(Map* map) {
6242 return StaticVisitorBase::GetVisitorId(map); 6244 return StaticVisitorBase::GetVisitorId(map);
6243 } 6245 }
6244 6246
6245 } // namespace internal 6247 } // namespace internal
6246 } // namespace v8 6248 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/heap-inl.h » ('j') | src/heap/heap-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698