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

Side by Side Diff: src/heap/mark-compact.cc

Issue 1040443002: MarkBit cleanup: They have to be accessed through Marking accessors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 void MarkCompactCollector::ClearMarkbits() { 477 void MarkCompactCollector::ClearMarkbits() {
478 ClearMarkbitsInPagedSpace(heap_->code_space()); 478 ClearMarkbitsInPagedSpace(heap_->code_space());
479 ClearMarkbitsInPagedSpace(heap_->map_space()); 479 ClearMarkbitsInPagedSpace(heap_->map_space());
480 ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); 480 ClearMarkbitsInPagedSpace(heap_->old_pointer_space());
481 ClearMarkbitsInPagedSpace(heap_->old_data_space()); 481 ClearMarkbitsInPagedSpace(heap_->old_data_space());
482 ClearMarkbitsInPagedSpace(heap_->cell_space()); 482 ClearMarkbitsInPagedSpace(heap_->cell_space());
483 ClearMarkbitsInNewSpace(heap_->new_space()); 483 ClearMarkbitsInNewSpace(heap_->new_space());
484 484
485 LargeObjectIterator it(heap_->lo_space()); 485 LargeObjectIterator it(heap_->lo_space());
486 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 486 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
487 MarkBit mark_bit = Marking::MarkBitFrom(obj); 487 Marking::MarkWhite(Marking::MarkBitFrom(obj));
488 mark_bit.Clear();
489 mark_bit.Next().Clear();
490 Page::FromAddress(obj->address())->ResetProgressBar(); 488 Page::FromAddress(obj->address())->ResetProgressBar();
491 Page::FromAddress(obj->address())->ResetLiveBytes(); 489 Page::FromAddress(obj->address())->ResetLiveBytes();
492 } 490 }
493 } 491 }
494 492
495 493
496 class MarkCompactCollector::SweeperTask : public v8::Task { 494 class MarkCompactCollector::SweeperTask : public v8::Task {
497 public: 495 public:
498 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} 496 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {}
499 497
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 // to only refill them for old data and pointer spaces. 574 // to only refill them for old data and pointer spaces.
577 return; 575 return;
578 } 576 }
579 577
580 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); 578 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
581 space->AddToAccountingStats(freed_bytes); 579 space->AddToAccountingStats(freed_bytes);
582 space->DecrementUnsweptFreeBytes(freed_bytes); 580 space->DecrementUnsweptFreeBytes(freed_bytes);
583 } 581 }
584 582
585 583
584 void Marking::SetAllMarkBitsInRange(MarkBit start, MarkBit end) {
585 MarkBit::CellType* start_cell = start.cell();
586 MarkBit::CellType* end_cell = end.cell();
587 MarkBit::CellType start_mask = ~(start.mask() - 1);
588 MarkBit::CellType end_mask = (end.mask() << 1) - 1;
589
590 if (start_cell == end_cell) {
591 *start_cell |= start_mask & end_mask;
592 } else {
593 *start_cell |= start_mask;
594 for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) {
595 *cell = ~0;
596 }
597 *end_cell |= end_mask;
598 }
599 }
600
601
602 void Marking::ClearAllMarkBitsOfCellsContainedInRange(MarkBit start,
603 MarkBit end) {
ulan 2015/03/27 08:36:55 This can clear bits outside [start, end] since we
Hannes Payer (out of office) 2015/03/30 15:09:25 I would have to expose the cell() call if we would
ulan 2015/03/30 15:17:40 OK
604 MarkBit::CellType* start_cell = start.cell();
605 MarkBit::CellType* end_cell = end.cell();
606 for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) {
607 *cell = 0;
608 }
609 }
610
611
586 void Marking::TransferMark(Address old_start, Address new_start) { 612 void Marking::TransferMark(Address old_start, Address new_start) {
587 // This is only used when resizing an object. 613 // This is only used when resizing an object.
588 DCHECK(MemoryChunk::FromAddress(old_start) == 614 DCHECK(MemoryChunk::FromAddress(old_start) ==
589 MemoryChunk::FromAddress(new_start)); 615 MemoryChunk::FromAddress(new_start));
590 616
591 if (!heap_->incremental_marking()->IsMarking()) return; 617 if (!heap_->incremental_marking()->IsMarking()) return;
592 618
593 // If the mark doesn't move, we don't check the color of the object. 619 // If the mark doesn't move, we don't check the color of the object.
594 // It doesn't matter whether the object is black, since it hasn't changed 620 // It doesn't matter whether the object is black, since it hasn't changed
595 // size, so the adjustment to the live data count will be zero anyway. 621 // size, so the adjustment to the live data count will be zero anyway.
596 if (old_start == new_start) return; 622 if (old_start == new_start) return;
597 623
598 MarkBit new_mark_bit = MarkBitFrom(new_start); 624 MarkBit new_mark_bit = MarkBitFrom(new_start);
599 MarkBit old_mark_bit = MarkBitFrom(old_start); 625 MarkBit old_mark_bit = MarkBitFrom(old_start);
600 626
601 #ifdef DEBUG 627 #ifdef DEBUG
602 ObjectColor old_color = Color(old_mark_bit); 628 ObjectColor old_color = Color(old_mark_bit);
603 #endif 629 #endif
604 630
605 if (Marking::IsBlack(old_mark_bit)) { 631 if (Marking::IsBlack(old_mark_bit)) {
606 old_mark_bit.Clear(); 632 Marking::BlackToWhite(old_mark_bit);
607 DCHECK(IsWhite(old_mark_bit));
608 Marking::MarkBlack(new_mark_bit); 633 Marking::MarkBlack(new_mark_bit);
609 return; 634 return;
610 } else if (Marking::IsGrey(old_mark_bit)) { 635 } else if (Marking::IsGrey(old_mark_bit)) {
611 old_mark_bit.Clear(); 636 Marking::GreyToWhite(old_mark_bit);
612 old_mark_bit.Next().Clear();
613 DCHECK(IsWhite(old_mark_bit));
614 heap_->incremental_marking()->WhiteToGreyAndPush( 637 heap_->incremental_marking()->WhiteToGreyAndPush(
615 HeapObject::FromAddress(new_start), new_mark_bit); 638 HeapObject::FromAddress(new_start), new_mark_bit);
616 heap_->incremental_marking()->RestartIfNotMarking(); 639 heap_->incremental_marking()->RestartIfNotMarking();
617 } 640 }
618 641
619 #ifdef DEBUG 642 #ifdef DEBUG
620 ObjectColor new_color = Color(new_mark_bit); 643 ObjectColor new_color = Color(new_mark_bit);
621 DCHECK(new_color == old_color); 644 DCHECK(new_color == old_color);
622 #endif 645 #endif
623 } 646 }
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 JSFunction* candidate = jsfunction_candidates_head_; 1010 JSFunction* candidate = jsfunction_candidates_head_;
988 JSFunction* next_candidate; 1011 JSFunction* next_candidate;
989 while (candidate != NULL) { 1012 while (candidate != NULL) {
990 next_candidate = GetNextCandidate(candidate); 1013 next_candidate = GetNextCandidate(candidate);
991 ClearNextCandidate(candidate, undefined); 1014 ClearNextCandidate(candidate, undefined);
992 1015
993 SharedFunctionInfo* shared = candidate->shared(); 1016 SharedFunctionInfo* shared = candidate->shared();
994 1017
995 Code* code = shared->code(); 1018 Code* code = shared->code();
996 MarkBit code_mark = Marking::MarkBitFrom(code); 1019 MarkBit code_mark = Marking::MarkBitFrom(code);
997 if (!code_mark.Get()) { 1020 if (Marking::IsWhite(code_mark)) {
998 if (FLAG_trace_code_flushing && shared->is_compiled()) { 1021 if (FLAG_trace_code_flushing && shared->is_compiled()) {
999 PrintF("[code-flushing clears: "); 1022 PrintF("[code-flushing clears: ");
1000 shared->ShortPrint(); 1023 shared->ShortPrint();
1001 PrintF(" - age: %d]\n", code->GetAge()); 1024 PrintF(" - age: %d]\n", code->GetAge());
1002 } 1025 }
1003 shared->set_code(lazy_compile); 1026 shared->set_code(lazy_compile);
1004 candidate->set_code(lazy_compile); 1027 candidate->set_code(lazy_compile);
1005 } else { 1028 } else {
1029 DCHECK(Marking::IsBlack(code_mark));
1006 candidate->set_code(code); 1030 candidate->set_code(code);
1007 } 1031 }
1008 1032
1009 // We are in the middle of a GC cycle so the write barrier in the code 1033 // We are in the middle of a GC cycle so the write barrier in the code
1010 // setter did not record the slot update and we have to do that manually. 1034 // setter did not record the slot update and we have to do that manually.
1011 Address slot = candidate->address() + JSFunction::kCodeEntryOffset; 1035 Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
1012 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); 1036 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
1013 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot(slot, 1037 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot(slot,
1014 target); 1038 target);
1015 1039
(...skipping 13 matching lines...) Expand all
1029 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); 1053 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy);
1030 1054
1031 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 1055 SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
1032 SharedFunctionInfo* next_candidate; 1056 SharedFunctionInfo* next_candidate;
1033 while (candidate != NULL) { 1057 while (candidate != NULL) {
1034 next_candidate = GetNextCandidate(candidate); 1058 next_candidate = GetNextCandidate(candidate);
1035 ClearNextCandidate(candidate); 1059 ClearNextCandidate(candidate);
1036 1060
1037 Code* code = candidate->code(); 1061 Code* code = candidate->code();
1038 MarkBit code_mark = Marking::MarkBitFrom(code); 1062 MarkBit code_mark = Marking::MarkBitFrom(code);
1039 if (!code_mark.Get()) { 1063 if (Marking::IsWhite(code_mark)) {
1040 if (FLAG_trace_code_flushing && candidate->is_compiled()) { 1064 if (FLAG_trace_code_flushing && candidate->is_compiled()) {
1041 PrintF("[code-flushing clears: "); 1065 PrintF("[code-flushing clears: ");
1042 candidate->ShortPrint(); 1066 candidate->ShortPrint();
1043 PrintF(" - age: %d]\n", code->GetAge()); 1067 PrintF(" - age: %d]\n", code->GetAge());
1044 } 1068 }
1045 candidate->set_code(lazy_compile); 1069 candidate->set_code(lazy_compile);
1046 } 1070 }
1047 1071
1048 Object** code_slot = 1072 Object** code_slot =
1049 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); 1073 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset);
(...skipping 17 matching lines...) Expand all
1067 next_holder = GetNextCodeMap(holder); 1091 next_holder = GetNextCodeMap(holder);
1068 ClearNextCodeMap(holder); 1092 ClearNextCodeMap(holder);
1069 1093
1070 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 1094 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map());
1071 int new_length = SharedFunctionInfo::kEntriesStart; 1095 int new_length = SharedFunctionInfo::kEntriesStart;
1072 int old_length = code_map->length(); 1096 int old_length = code_map->length();
1073 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length; 1097 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length;
1074 i += SharedFunctionInfo::kEntryLength) { 1098 i += SharedFunctionInfo::kEntryLength) {
1075 Code* code = 1099 Code* code =
1076 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset)); 1100 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset));
1077 if (!Marking::MarkBitFrom(code).Get()) continue; 1101 if (Marking::IsWhite(Marking::MarkBitFrom(code))) continue;
1078 1102 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(code)));
1079 // Move every slot in the entry. 1103 // Move every slot in the entry.
1080 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) { 1104 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) {
1081 int dst_index = new_length++; 1105 int dst_index = new_length++;
1082 Object** slot = code_map->RawFieldOfElementAt(dst_index); 1106 Object** slot = code_map->RawFieldOfElementAt(dst_index);
1083 Object* object = code_map->get(i + j); 1107 Object* object = code_map->get(i + j);
1084 code_map->set(dst_index, object); 1108 code_map->set(dst_index, object);
1085 if (j == SharedFunctionInfo::kOsrAstIdOffset) { 1109 if (j == SharedFunctionInfo::kOsrAstIdOffset) {
1086 DCHECK(object->IsSmi()); 1110 DCHECK(object->IsSmi());
1087 } else { 1111 } else {
1088 DCHECK( 1112 DCHECK(
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 // Marks the object black and pushes it on the marking stack. 1368 // Marks the object black and pushes it on the marking stack.
1345 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { 1369 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
1346 MarkBit mark = Marking::MarkBitFrom(object); 1370 MarkBit mark = Marking::MarkBitFrom(object);
1347 heap->mark_compact_collector()->MarkObject(object, mark); 1371 heap->mark_compact_collector()->MarkObject(object, mark);
1348 } 1372 }
1349 1373
1350 // Marks the object black without pushing it on the marking stack. 1374 // Marks the object black without pushing it on the marking stack.
1351 // Returns true if object needed marking and false otherwise. 1375 // Returns true if object needed marking and false otherwise.
1352 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { 1376 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
1353 MarkBit mark_bit = Marking::MarkBitFrom(object); 1377 MarkBit mark_bit = Marking::MarkBitFrom(object);
1354 if (!mark_bit.Get()) { 1378 if (Marking::IsWhite(mark_bit)) {
1355 heap->mark_compact_collector()->SetMark(object, mark_bit); 1379 heap->mark_compact_collector()->SetMark(object, mark_bit);
1356 return true; 1380 return true;
1357 } 1381 }
1358 return false; 1382 return false;
1359 } 1383 }
1360 1384
1361 // Mark object pointed to by p. 1385 // Mark object pointed to by p.
1362 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 1386 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector,
1363 Object** anchor_slot, Object** p)) { 1387 Object** anchor_slot, Object** p)) {
1364 if (!(*p)->IsHeapObject()) return; 1388 if (!(*p)->IsHeapObject()) return;
(...skipping 30 matching lines...) Expand all
1395 if (check.HasOverflowed()) return false; 1419 if (check.HasOverflowed()) return false;
1396 1420
1397 MarkCompactCollector* collector = heap->mark_compact_collector(); 1421 MarkCompactCollector* collector = heap->mark_compact_collector();
1398 // Visit the unmarked objects. 1422 // Visit the unmarked objects.
1399 for (Object** p = start; p < end; p++) { 1423 for (Object** p = start; p < end; p++) {
1400 Object* o = *p; 1424 Object* o = *p;
1401 if (!o->IsHeapObject()) continue; 1425 if (!o->IsHeapObject()) continue;
1402 collector->RecordSlot(start, p, o); 1426 collector->RecordSlot(start, p, o);
1403 HeapObject* obj = HeapObject::cast(o); 1427 HeapObject* obj = HeapObject::cast(o);
1404 MarkBit mark = Marking::MarkBitFrom(obj); 1428 MarkBit mark = Marking::MarkBitFrom(obj);
1405 if (mark.Get()) continue; 1429 if (Marking::IsMarked(mark)) continue;
1406 VisitUnmarkedObject(collector, obj); 1430 VisitUnmarkedObject(collector, obj);
1407 } 1431 }
1408 return true; 1432 return true;
1409 } 1433 }
1410 1434
1411 private: 1435 private:
1412 template <int id> 1436 template <int id>
1413 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); 1437 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
1414 1438
1415 // Code flushing support. 1439 // Code flushing support.
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 // ProcessTopOptimizedFrame. 1764 // ProcessTopOptimizedFrame.
1741 void VisitNextCodeLink(Object** p) {} 1765 void VisitNextCodeLink(Object** p) {}
1742 1766
1743 private: 1767 private:
1744 void MarkObjectByPointer(Object** p) { 1768 void MarkObjectByPointer(Object** p) {
1745 if (!(*p)->IsHeapObject()) return; 1769 if (!(*p)->IsHeapObject()) return;
1746 1770
1747 // Replace flat cons strings in place. 1771 // Replace flat cons strings in place.
1748 HeapObject* object = ShortCircuitConsString(p); 1772 HeapObject* object = ShortCircuitConsString(p);
1749 MarkBit mark_bit = Marking::MarkBitFrom(object); 1773 MarkBit mark_bit = Marking::MarkBitFrom(object);
1750 if (mark_bit.Get()) return; 1774 if (Marking::IsMarked(mark_bit)) return;
1751 1775
1752 Map* map = object->map(); 1776 Map* map = object->map();
1753 // Mark the object. 1777 // Mark the object.
1754 collector_->SetMark(object, mark_bit); 1778 collector_->SetMark(object, mark_bit);
1755 1779
1756 // Mark the map pointer and body, and push them on the marking stack. 1780 // Mark the map pointer and body, and push them on the marking stack.
1757 MarkBit map_mark = Marking::MarkBitFrom(map); 1781 MarkBit map_mark = Marking::MarkBitFrom(map);
1758 collector_->MarkObject(map, map_mark); 1782 collector_->MarkObject(map, map_mark);
1759 MarkCompactMarkingVisitor::IterateBody(map, object); 1783 MarkCompactMarkingVisitor::IterateBody(map, object);
1760 1784
(...skipping 10 matching lines...) Expand all
1771 template <bool finalize_external_strings> 1795 template <bool finalize_external_strings>
1772 class StringTableCleaner : public ObjectVisitor { 1796 class StringTableCleaner : public ObjectVisitor {
1773 public: 1797 public:
1774 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {} 1798 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {}
1775 1799
1776 virtual void VisitPointers(Object** start, Object** end) { 1800 virtual void VisitPointers(Object** start, Object** end) {
1777 // Visit all HeapObject pointers in [start, end). 1801 // Visit all HeapObject pointers in [start, end).
1778 for (Object** p = start; p < end; p++) { 1802 for (Object** p = start; p < end; p++) {
1779 Object* o = *p; 1803 Object* o = *p;
1780 if (o->IsHeapObject() && 1804 if (o->IsHeapObject() &&
1781 !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { 1805 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(o)))) {
1782 if (finalize_external_strings) { 1806 if (finalize_external_strings) {
1783 DCHECK(o->IsExternalString()); 1807 DCHECK(o->IsExternalString());
1784 heap_->FinalizeExternalString(String::cast(*p)); 1808 heap_->FinalizeExternalString(String::cast(*p));
1785 } else { 1809 } else {
1786 pointers_removed_++; 1810 pointers_removed_++;
1787 } 1811 }
1788 // Set the entry to the_hole_value (as deleted). 1812 // Set the entry to the_hole_value (as deleted).
1789 *p = heap_->the_hole_value(); 1813 *p = heap_->the_hole_value();
1790 } 1814 }
1791 } 1815 }
(...skipping 12 matching lines...) Expand all
1804 1828
1805 typedef StringTableCleaner<false> InternalizedStringTableCleaner; 1829 typedef StringTableCleaner<false> InternalizedStringTableCleaner;
1806 typedef StringTableCleaner<true> ExternalStringTableCleaner; 1830 typedef StringTableCleaner<true> ExternalStringTableCleaner;
1807 1831
1808 1832
1809 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1833 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
1810 // are retained. 1834 // are retained.
1811 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1835 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
1812 public: 1836 public:
1813 virtual Object* RetainAs(Object* object) { 1837 virtual Object* RetainAs(Object* object) {
1814 if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { 1838 if (Marking::IsMarked(Marking::MarkBitFrom(HeapObject::cast(object)))) {
1815 return object; 1839 return object;
1816 } else if (object->IsAllocationSite() && 1840 } else if (object->IsAllocationSite() &&
1817 !(AllocationSite::cast(object)->IsZombie())) { 1841 !(AllocationSite::cast(object)->IsZombie())) {
1818 // "dead" AllocationSites need to live long enough for a traversal of new 1842 // "dead" AllocationSites need to live long enough for a traversal of new
1819 // space. These sites get a one-time reprieve. 1843 // space. These sites get a one-time reprieve.
1820 AllocationSite* site = AllocationSite::cast(object); 1844 AllocationSite* site = AllocationSite::cast(object);
1821 site->MarkZombie(); 1845 site->MarkZombie();
1822 site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site); 1846 site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site);
1823 return object; 1847 return object;
1824 } else { 1848 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 } else { 1902 } else {
1879 grey_objects = current_cell & (current_cell >> 1); 1903 grey_objects = current_cell & (current_cell >> 1);
1880 } 1904 }
1881 1905
1882 int offset = 0; 1906 int offset = 0;
1883 while (grey_objects != 0) { 1907 while (grey_objects != 0) {
1884 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); 1908 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects);
1885 grey_objects >>= trailing_zeros; 1909 grey_objects >>= trailing_zeros;
1886 offset += trailing_zeros; 1910 offset += trailing_zeros;
1887 MarkBit markbit(cell, 1 << offset, false); 1911 MarkBit markbit(cell, 1 << offset, false);
1888 DCHECK(Marking::IsGrey(markbit));
1889 Marking::GreyToBlack(markbit); 1912 Marking::GreyToBlack(markbit);
1890 Address addr = cell_base + offset * kPointerSize; 1913 Address addr = cell_base + offset * kPointerSize;
1891 HeapObject* object = HeapObject::FromAddress(addr); 1914 HeapObject* object = HeapObject::FromAddress(addr);
1892 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 1915 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size());
1893 marking_deque->PushBlack(object); 1916 marking_deque->PushBlack(object);
1894 if (marking_deque->IsFull()) return; 1917 if (marking_deque->IsFull()) return;
1895 offset += 2; 1918 offset += 2;
1896 grey_objects >>= 2; 1919 grey_objects >>= 2;
1897 } 1920 }
1898 1921
(...skipping 19 matching lines...) Expand all
1918 MarkBit::CellType current_cell = *cell; 1941 MarkBit::CellType current_cell = *cell;
1919 if (current_cell == 0) continue; 1942 if (current_cell == 0) continue;
1920 1943
1921 int offset = 0; 1944 int offset = 0;
1922 while (current_cell != 0) { 1945 while (current_cell != 0) {
1923 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); 1946 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
1924 current_cell >>= trailing_zeros; 1947 current_cell >>= trailing_zeros;
1925 offset += trailing_zeros; 1948 offset += trailing_zeros;
1926 Address address = cell_base + offset * kPointerSize; 1949 Address address = cell_base + offset * kPointerSize;
1927 HeapObject* object = HeapObject::FromAddress(address); 1950 HeapObject* object = HeapObject::FromAddress(address);
1951 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
1928 1952
1929 int size = object->Size(); 1953 int size = object->Size();
1930 survivors_size += size; 1954 survivors_size += size;
1931 1955
1932 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); 1956 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT);
1933 1957
1934 offset++; 1958 offset += 2;
1935 current_cell >>= 1; 1959 current_cell >>= 2;
1936 1960
1937 // TODO(hpayer): Refactor EvacuateObject and call this function instead. 1961 // TODO(hpayer): Refactor EvacuateObject and call this function instead.
1938 if (heap()->ShouldBePromoted(object->address(), size)) { 1962 if (heap()->ShouldBePromoted(object->address(), size)) {
1939 if (!TryPromoteObject(object, size)) { 1963 if (!TryPromoteObject(object, size)) {
1940 V8::FatalProcessOutOfMemory("Full GC promotion failed"); 1964 V8::FatalProcessOutOfMemory("Full GC promotion failed");
1941 } 1965 }
1942 } else { 1966 } else {
1943 AllocationResult allocation = new_space->AllocateRaw(size); 1967 AllocationResult allocation = new_space->AllocateRaw(size);
1944 if (allocation.IsRetry()) { 1968 if (allocation.IsRetry()) {
1945 if (!new_space->AddFreshPage()) { 1969 if (!new_space->AddFreshPage()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1984 if (marking_deque->IsFull()) return; 2008 if (marking_deque->IsFull()) return;
1985 } 2009 }
1986 } 2010 }
1987 2011
1988 2012
1989 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 2013 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1990 Object* o = *p; 2014 Object* o = *p;
1991 if (!o->IsHeapObject()) return false; 2015 if (!o->IsHeapObject()) return false;
1992 HeapObject* heap_object = HeapObject::cast(o); 2016 HeapObject* heap_object = HeapObject::cast(o);
1993 MarkBit mark = Marking::MarkBitFrom(heap_object); 2017 MarkBit mark = Marking::MarkBitFrom(heap_object);
1994 return !mark.Get(); 2018 return Marking::IsWhite(mark);
1995 } 2019 }
1996 2020
1997 2021
1998 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, 2022 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
1999 Object** p) { 2023 Object** p) {
2000 Object* o = *p; 2024 Object* o = *p;
2001 DCHECK(o->IsHeapObject()); 2025 DCHECK(o->IsHeapObject());
2002 HeapObject* heap_object = HeapObject::cast(o); 2026 HeapObject* heap_object = HeapObject::cast(o);
2003 MarkBit mark = Marking::MarkBitFrom(heap_object); 2027 MarkBit mark = Marking::MarkBitFrom(heap_object);
2004 return !mark.Get(); 2028 return Marking::IsWhite(mark);
2005 } 2029 }
2006 2030
2007 2031
2008 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { 2032 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
2009 StringTable* string_table = heap()->string_table(); 2033 StringTable* string_table = heap()->string_table();
2010 // Mark the string table itself. 2034 // Mark the string table itself.
2011 MarkBit string_table_mark = Marking::MarkBitFrom(string_table); 2035 MarkBit string_table_mark = Marking::MarkBitFrom(string_table);
2012 if (!string_table_mark.Get()) { 2036 if (Marking::IsWhite(string_table_mark)) {
2013 // String table could have already been marked by visiting the handles list. 2037 // String table could have already been marked by visiting the handles list.
2014 SetMark(string_table, string_table_mark); 2038 SetMark(string_table, string_table_mark);
2015 } 2039 }
2016 // Explicitly mark the prefix. 2040 // Explicitly mark the prefix.
2017 string_table->IteratePrefix(visitor); 2041 string_table->IteratePrefix(visitor);
2018 ProcessMarkingDeque(); 2042 ProcessMarkingDeque();
2019 } 2043 }
2020 2044
2021 2045
2022 void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) { 2046 void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 int length = retained_maps->Length(); 2219 int length = retained_maps->Length();
2196 int new_length = 0; 2220 int new_length = 0;
2197 for (int i = 0; i < length; i += 2) { 2221 for (int i = 0; i < length; i += 2) {
2198 DCHECK(retained_maps->Get(i)->IsWeakCell()); 2222 DCHECK(retained_maps->Get(i)->IsWeakCell());
2199 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); 2223 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
2200 if (cell->cleared()) continue; 2224 if (cell->cleared()) continue;
2201 int age = Smi::cast(retained_maps->Get(i + 1))->value(); 2225 int age = Smi::cast(retained_maps->Get(i + 1))->value();
2202 int new_age; 2226 int new_age;
2203 Map* map = Map::cast(cell->value()); 2227 Map* map = Map::cast(cell->value());
2204 MarkBit map_mark = Marking::MarkBitFrom(map); 2228 MarkBit map_mark = Marking::MarkBitFrom(map);
2205 if (!map_mark.Get()) { 2229 if (Marking::IsWhite(map_mark)) {
2206 if (age == 0) { 2230 if (age == 0) {
2207 // The map has aged. Do not retain this map. 2231 // The map has aged. Do not retain this map.
2208 continue; 2232 continue;
2209 } 2233 }
2210 Object* constructor = map->GetConstructor(); 2234 Object* constructor = map->GetConstructor();
2211 if (!constructor->IsHeapObject() || 2235 if (!constructor->IsHeapObject() || Marking::IsWhite(Marking::MarkBitFrom(
2212 !Marking::MarkBitFrom(HeapObject::cast(constructor)).Get()) { 2236 HeapObject::cast(constructor)))) {
2213 // The constructor is dead, no new objects with this map can 2237 // The constructor is dead, no new objects with this map can
2214 // be created. Do not retain this map. 2238 // be created. Do not retain this map.
2215 continue; 2239 continue;
2216 } 2240 }
2217 Object* prototype = map->prototype(); 2241 Object* prototype = map->prototype();
2218 if (prototype->IsHeapObject() && 2242 if (prototype->IsHeapObject() &&
2219 !Marking::MarkBitFrom(HeapObject::cast(prototype)).Get()) { 2243 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) {
2220 // The prototype is not marked, age the map. 2244 // The prototype is not marked, age the map.
2221 new_age = age - 1; 2245 new_age = age - 1;
2222 } else { 2246 } else {
2223 // The prototype and the constructor are marked, this map keeps only 2247 // The prototype and the constructor are marked, this map keeps only
2224 // transition tree alive, not JSObjects. Do not age the map. 2248 // transition tree alive, not JSObjects. Do not age the map.
2225 new_age = age; 2249 new_age = age;
2226 } 2250 }
2227 MarkObject(map, map_mark); 2251 MarkObject(map, map_mark);
2228 } else { 2252 } else {
2229 new_age = FLAG_retain_maps_for_n_gc; 2253 new_age = FLAG_retain_maps_for_n_gc;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 for (HeapObject* obj = map_iterator.Next(); obj != NULL; 2447 for (HeapObject* obj = map_iterator.Next(); obj != NULL;
2424 obj = map_iterator.Next()) { 2448 obj = map_iterator.Next()) {
2425 Map* map = Map::cast(obj); 2449 Map* map = Map::cast(obj);
2426 2450
2427 if (!map->CanTransition()) continue; 2451 if (!map->CanTransition()) continue;
2428 2452
2429 MarkBit map_mark = Marking::MarkBitFrom(map); 2453 MarkBit map_mark = Marking::MarkBitFrom(map);
2430 ClearNonLivePrototypeTransitions(map); 2454 ClearNonLivePrototypeTransitions(map);
2431 ClearNonLiveMapTransitions(map, map_mark); 2455 ClearNonLiveMapTransitions(map, map_mark);
2432 2456
2433 if (!map_mark.Get()) { 2457 if (Marking::IsWhite(map_mark)) {
2434 have_code_to_deoptimize_ |= 2458 have_code_to_deoptimize_ |=
2435 map->dependent_code()->MarkCodeForDeoptimization( 2459 map->dependent_code()->MarkCodeForDeoptimization(
2436 isolate(), DependentCode::kWeakCodeGroup); 2460 isolate(), DependentCode::kWeakCodeGroup);
2437 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); 2461 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2438 } 2462 }
2439 } 2463 }
2440 2464
2441 WeakHashTable* table = heap_->weak_object_to_code_table(); 2465 WeakHashTable* table = heap_->weak_object_to_code_table();
2442 uint32_t capacity = table->Capacity(); 2466 uint32_t capacity = table->Capacity();
2443 for (uint32_t i = 0; i < capacity; i++) { 2467 for (uint32_t i = 0; i < capacity; i++) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 2515
2492 2516
2493 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, 2517 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
2494 MarkBit map_mark) { 2518 MarkBit map_mark) {
2495 Object* potential_parent = map->GetBackPointer(); 2519 Object* potential_parent = map->GetBackPointer();
2496 if (!potential_parent->IsMap()) return; 2520 if (!potential_parent->IsMap()) return;
2497 Map* parent = Map::cast(potential_parent); 2521 Map* parent = Map::cast(potential_parent);
2498 2522
2499 // Follow back pointer, check whether we are dealing with a map transition 2523 // Follow back pointer, check whether we are dealing with a map transition
2500 // from a live map to a dead path and in case clear transitions of parent. 2524 // from a live map to a dead path and in case clear transitions of parent.
2501 bool current_is_alive = map_mark.Get(); 2525 bool current_is_alive = Marking::IsMarked(map_mark);
2502 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2526 bool parent_is_alive = Marking::IsMarked(Marking::MarkBitFrom(parent));
2503 if (!current_is_alive && parent_is_alive) { 2527 if (!current_is_alive && parent_is_alive) {
2504 ClearMapTransitions(parent, map); 2528 ClearMapTransitions(parent, map);
2505 } 2529 }
2506 } 2530 }
2507 2531
2508 2532
2509 // Clear a possible back pointer in case the transition leads to a dead map. 2533 // Clear a possible back pointer in case the transition leads to a dead map.
2510 // Return true in case a back pointer has been cleared and false otherwise. 2534 // Return true in case a back pointer has been cleared and false otherwise.
2511 bool MarkCompactCollector::ClearMapBackPointer(Map* target) { 2535 bool MarkCompactCollector::ClearMapBackPointer(Map* target) {
2512 if (Marking::MarkBitFrom(target).Get()) return false; 2536 if (Marking::IsMarked(Marking::MarkBitFrom(target))) return false;
2513 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER); 2537 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER);
2514 return true; 2538 return true;
2515 } 2539 }
2516 2540
2517 2541
2518 void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) { 2542 void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) {
2519 Object* transitions = map->raw_transitions(); 2543 Object* transitions = map->raw_transitions();
2520 int num_transitions = TransitionArray::NumberOfTransitions(transitions); 2544 int num_transitions = TransitionArray::NumberOfTransitions(transitions);
2521 2545
2522 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 2546 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after
3556 return false; 3580 return false;
3557 } 3581 }
3558 3582
3559 Address code_start = code->address(); 3583 Address code_start = code->address();
3560 Address code_end = code_start + code->Size(); 3584 Address code_end = code_start + code->Size();
3561 3585
3562 uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start); 3586 uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start);
3563 uint32_t end_index = 3587 uint32_t end_index =
3564 MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize); 3588 MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize);
3565 3589
3590 // TODO(hpayer): Filter out invalidated code in
3591 // ClearInvalidSlotsBufferEntries.
3566 Bitmap* b = p->markbits(); 3592 Bitmap* b = p->markbits();
3567 3593
3568 MarkBit start_mark_bit = b->MarkBitFromIndex(start_index); 3594 MarkBit start_mark_bit = b->MarkBitFromIndex(start_index);
3569 MarkBit end_mark_bit = b->MarkBitFromIndex(end_index); 3595 MarkBit end_mark_bit = b->MarkBitFromIndex(end_index);
3570 3596
3571 MarkBit::CellType* start_cell = start_mark_bit.cell();
3572 MarkBit::CellType* end_cell = end_mark_bit.cell();
3573
3574 if (value) { 3597 if (value) {
3575 MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1); 3598 Marking::SetAllMarkBitsInRange(start_mark_bit, end_mark_bit);
3576 MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1;
3577
3578 if (start_cell == end_cell) {
3579 *start_cell |= start_mask & end_mask;
3580 } else {
3581 *start_cell |= start_mask;
3582 for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) {
3583 *cell = ~0;
3584 }
3585 *end_cell |= end_mask;
3586 }
3587 } else { 3599 } else {
3588 for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) { 3600 Marking::ClearAllMarkBitsOfCellsContainedInRange(start_mark_bit,
3589 *cell = 0; 3601 end_mark_bit);
3590 }
3591 } 3602 }
3592 3603
3593 return true; 3604 return true;
3594 } 3605 }
3595 3606
3596 3607
3597 static bool IsOnInvalidatedCodeObject(Address addr) { 3608 static bool IsOnInvalidatedCodeObject(Address addr) {
3598 // We did not record any slots in large objects thus 3609 // We did not record any slots in large objects thus
3599 // we can safely go to the page from the slot address. 3610 // we can safely go to the page from the slot address.
3600 Page* p = Page::FromAddress(addr); 3611 Page* p = Page::FromAddress(addr);
3601 3612
3602 // First check owner's identity because old pointer and old data spaces 3613 // First check owner's identity because old pointer and old data spaces
3603 // are swept lazily and might still have non-zero mark-bits on some 3614 // are swept lazily and might still have non-zero mark-bits on some
3604 // pages. 3615 // pages.
3605 if (p->owner()->identity() != CODE_SPACE) return false; 3616 if (p->owner()->identity() != CODE_SPACE) return false;
3606 3617
3607 // In code space only bits on evacuation candidates (but we don't record 3618 // In code space only bits on evacuation candidates (but we don't record
3608 // any slots on them) and under invalidated code objects are non-zero. 3619 // any slots on them) and under invalidated code objects are non-zero.
3609 MarkBit mark_bit = 3620 MarkBit mark_bit =
3610 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 3621 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr));
3611 3622
3612 return mark_bit.Get(); 3623 return Marking::IsMarked(mark_bit);
3613 } 3624 }
3614 3625
3615 3626
3616 void MarkCompactCollector::InvalidateCode(Code* code) { 3627 void MarkCompactCollector::InvalidateCode(Code* code) {
3617 if (heap_->incremental_marking()->IsCompacting() && 3628 if (heap_->incremental_marking()->IsCompacting() &&
3618 !ShouldSkipEvacuationSlotRecording(code)) { 3629 !ShouldSkipEvacuationSlotRecording(code)) {
3619 DCHECK(compacting_); 3630 DCHECK(compacting_);
3620 3631
3621 // If the object is white than no slots were recorded on it yet. 3632 // If the object is white than no slots were recorded on it yet.
3622 MarkBit mark_bit = Marking::MarkBitFrom(code); 3633 MarkBit mark_bit = Marking::MarkBitFrom(code);
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
4750 SlotsBuffer* buffer = *buffer_address; 4761 SlotsBuffer* buffer = *buffer_address;
4751 while (buffer != NULL) { 4762 while (buffer != NULL) {
4752 SlotsBuffer* next_buffer = buffer->next(); 4763 SlotsBuffer* next_buffer = buffer->next();
4753 DeallocateBuffer(buffer); 4764 DeallocateBuffer(buffer);
4754 buffer = next_buffer; 4765 buffer = next_buffer;
4755 } 4766 }
4756 *buffer_address = NULL; 4767 *buffer_address = NULL;
4757 } 4768 }
4758 } 4769 }
4759 } // namespace v8::internal 4770 } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698