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

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, 8 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 467
468 void MarkCompactCollector::ClearMarkbits() { 468 void MarkCompactCollector::ClearMarkbits() {
469 ClearMarkbitsInPagedSpace(heap_->code_space()); 469 ClearMarkbitsInPagedSpace(heap_->code_space());
470 ClearMarkbitsInPagedSpace(heap_->map_space()); 470 ClearMarkbitsInPagedSpace(heap_->map_space());
471 ClearMarkbitsInPagedSpace(heap_->old_space()); 471 ClearMarkbitsInPagedSpace(heap_->old_space());
472 ClearMarkbitsInPagedSpace(heap_->cell_space()); 472 ClearMarkbitsInPagedSpace(heap_->cell_space());
473 ClearMarkbitsInNewSpace(heap_->new_space()); 473 ClearMarkbitsInNewSpace(heap_->new_space());
474 474
475 LargeObjectIterator it(heap_->lo_space()); 475 LargeObjectIterator it(heap_->lo_space());
476 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 476 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
477 MarkBit mark_bit = Marking::MarkBitFrom(obj); 477 Marking::MarkWhite(Marking::MarkBitFrom(obj));
478 mark_bit.Clear();
479 mark_bit.Next().Clear();
480 Page::FromAddress(obj->address())->ResetProgressBar(); 478 Page::FromAddress(obj->address())->ResetProgressBar();
481 Page::FromAddress(obj->address())->ResetLiveBytes(); 479 Page::FromAddress(obj->address())->ResetLiveBytes();
482 } 480 }
483 } 481 }
484 482
485 483
486 class MarkCompactCollector::SweeperTask : public v8::Task { 484 class MarkCompactCollector::SweeperTask : public v8::Task {
487 public: 485 public:
488 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} 486 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {}
489 487
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 // to only refill them for the old space. 554 // to only refill them for the old space.
557 return; 555 return;
558 } 556 }
559 557
560 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); 558 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
561 space->AddToAccountingStats(freed_bytes); 559 space->AddToAccountingStats(freed_bytes);
562 space->DecrementUnsweptFreeBytes(freed_bytes); 560 space->DecrementUnsweptFreeBytes(freed_bytes);
563 } 561 }
564 562
565 563
564 void Marking::SetAllMarkBitsInRange(MarkBit start, MarkBit end) {
565 MarkBit::CellType* start_cell = start.cell();
566 MarkBit::CellType* end_cell = end.cell();
567 MarkBit::CellType start_mask = ~(start.mask() - 1);
568 MarkBit::CellType end_mask = (end.mask() << 1) - 1;
569
570 if (start_cell == end_cell) {
571 *start_cell |= start_mask & end_mask;
572 } else {
573 *start_cell |= start_mask;
574 for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) {
575 *cell = ~0;
576 }
577 *end_cell |= end_mask;
578 }
579 }
580
581
582 void Marking::ClearAllMarkBitsOfCellsContainedInRange(MarkBit start,
583 MarkBit end) {
584 MarkBit::CellType* start_cell = start.cell();
585 MarkBit::CellType* end_cell = end.cell();
586 for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) {
587 *cell = 0;
588 }
589 }
590
591
566 void Marking::TransferMark(Address old_start, Address new_start) { 592 void Marking::TransferMark(Address old_start, Address new_start) {
567 // This is only used when resizing an object. 593 // This is only used when resizing an object.
568 DCHECK(MemoryChunk::FromAddress(old_start) == 594 DCHECK(MemoryChunk::FromAddress(old_start) ==
569 MemoryChunk::FromAddress(new_start)); 595 MemoryChunk::FromAddress(new_start));
570 596
571 if (!heap_->incremental_marking()->IsMarking()) return; 597 if (!heap_->incremental_marking()->IsMarking()) return;
572 598
573 // If the mark doesn't move, we don't check the color of the object. 599 // If the mark doesn't move, we don't check the color of the object.
574 // It doesn't matter whether the object is black, since it hasn't changed 600 // It doesn't matter whether the object is black, since it hasn't changed
575 // size, so the adjustment to the live data count will be zero anyway. 601 // size, so the adjustment to the live data count will be zero anyway.
576 if (old_start == new_start) return; 602 if (old_start == new_start) return;
577 603
578 MarkBit new_mark_bit = MarkBitFrom(new_start); 604 MarkBit new_mark_bit = MarkBitFrom(new_start);
579 MarkBit old_mark_bit = MarkBitFrom(old_start); 605 MarkBit old_mark_bit = MarkBitFrom(old_start);
580 606
581 #ifdef DEBUG 607 #ifdef DEBUG
582 ObjectColor old_color = Color(old_mark_bit); 608 ObjectColor old_color = Color(old_mark_bit);
583 #endif 609 #endif
584 610
585 if (Marking::IsBlack(old_mark_bit)) { 611 if (Marking::IsBlack(old_mark_bit)) {
586 old_mark_bit.Clear(); 612 Marking::BlackToWhite(old_mark_bit);
587 DCHECK(IsWhite(old_mark_bit));
588 Marking::MarkBlack(new_mark_bit); 613 Marking::MarkBlack(new_mark_bit);
589 return; 614 return;
590 } else if (Marking::IsGrey(old_mark_bit)) { 615 } else if (Marking::IsGrey(old_mark_bit)) {
591 old_mark_bit.Clear(); 616 Marking::GreyToWhite(old_mark_bit);
592 old_mark_bit.Next().Clear();
593 DCHECK(IsWhite(old_mark_bit));
594 heap_->incremental_marking()->WhiteToGreyAndPush( 617 heap_->incremental_marking()->WhiteToGreyAndPush(
595 HeapObject::FromAddress(new_start), new_mark_bit); 618 HeapObject::FromAddress(new_start), new_mark_bit);
596 heap_->incremental_marking()->RestartIfNotMarking(); 619 heap_->incremental_marking()->RestartIfNotMarking();
597 } 620 }
598 621
599 #ifdef DEBUG 622 #ifdef DEBUG
600 ObjectColor new_color = Color(new_mark_bit); 623 ObjectColor new_color = Color(new_mark_bit);
601 DCHECK(new_color == old_color); 624 DCHECK(new_color == old_color);
602 #endif 625 #endif
603 } 626 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 JSFunction* candidate = jsfunction_candidates_head_; 986 JSFunction* candidate = jsfunction_candidates_head_;
964 JSFunction* next_candidate; 987 JSFunction* next_candidate;
965 while (candidate != NULL) { 988 while (candidate != NULL) {
966 next_candidate = GetNextCandidate(candidate); 989 next_candidate = GetNextCandidate(candidate);
967 ClearNextCandidate(candidate, undefined); 990 ClearNextCandidate(candidate, undefined);
968 991
969 SharedFunctionInfo* shared = candidate->shared(); 992 SharedFunctionInfo* shared = candidate->shared();
970 993
971 Code* code = shared->code(); 994 Code* code = shared->code();
972 MarkBit code_mark = Marking::MarkBitFrom(code); 995 MarkBit code_mark = Marking::MarkBitFrom(code);
973 if (!code_mark.Get()) { 996 if (Marking::IsWhite(code_mark)) {
974 if (FLAG_trace_code_flushing && shared->is_compiled()) { 997 if (FLAG_trace_code_flushing && shared->is_compiled()) {
975 PrintF("[code-flushing clears: "); 998 PrintF("[code-flushing clears: ");
976 shared->ShortPrint(); 999 shared->ShortPrint();
977 PrintF(" - age: %d]\n", code->GetAge()); 1000 PrintF(" - age: %d]\n", code->GetAge());
978 } 1001 }
979 shared->set_code(lazy_compile); 1002 shared->set_code(lazy_compile);
980 candidate->set_code(lazy_compile); 1003 candidate->set_code(lazy_compile);
981 } else { 1004 } else {
1005 DCHECK(Marking::IsBlack(code_mark));
982 candidate->set_code(code); 1006 candidate->set_code(code);
983 } 1007 }
984 1008
985 // We are in the middle of a GC cycle so the write barrier in the code 1009 // We are in the middle of a GC cycle so the write barrier in the code
986 // setter did not record the slot update and we have to do that manually. 1010 // setter did not record the slot update and we have to do that manually.
987 Address slot = candidate->address() + JSFunction::kCodeEntryOffset; 1011 Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
988 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); 1012 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
989 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot(slot, 1013 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot(slot,
990 target); 1014 target);
991 1015
(...skipping 13 matching lines...) Expand all
1005 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); 1029 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy);
1006 1030
1007 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 1031 SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
1008 SharedFunctionInfo* next_candidate; 1032 SharedFunctionInfo* next_candidate;
1009 while (candidate != NULL) { 1033 while (candidate != NULL) {
1010 next_candidate = GetNextCandidate(candidate); 1034 next_candidate = GetNextCandidate(candidate);
1011 ClearNextCandidate(candidate); 1035 ClearNextCandidate(candidate);
1012 1036
1013 Code* code = candidate->code(); 1037 Code* code = candidate->code();
1014 MarkBit code_mark = Marking::MarkBitFrom(code); 1038 MarkBit code_mark = Marking::MarkBitFrom(code);
1015 if (!code_mark.Get()) { 1039 if (Marking::IsWhite(code_mark)) {
1016 if (FLAG_trace_code_flushing && candidate->is_compiled()) { 1040 if (FLAG_trace_code_flushing && candidate->is_compiled()) {
1017 PrintF("[code-flushing clears: "); 1041 PrintF("[code-flushing clears: ");
1018 candidate->ShortPrint(); 1042 candidate->ShortPrint();
1019 PrintF(" - age: %d]\n", code->GetAge()); 1043 PrintF(" - age: %d]\n", code->GetAge());
1020 } 1044 }
1021 candidate->set_code(lazy_compile); 1045 candidate->set_code(lazy_compile);
1022 } 1046 }
1023 1047
1024 Object** code_slot = 1048 Object** code_slot =
1025 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); 1049 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset);
(...skipping 17 matching lines...) Expand all
1043 next_holder = GetNextCodeMap(holder); 1067 next_holder = GetNextCodeMap(holder);
1044 ClearNextCodeMap(holder); 1068 ClearNextCodeMap(holder);
1045 1069
1046 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 1070 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map());
1047 int new_length = SharedFunctionInfo::kEntriesStart; 1071 int new_length = SharedFunctionInfo::kEntriesStart;
1048 int old_length = code_map->length(); 1072 int old_length = code_map->length();
1049 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length; 1073 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length;
1050 i += SharedFunctionInfo::kEntryLength) { 1074 i += SharedFunctionInfo::kEntryLength) {
1051 Code* code = 1075 Code* code =
1052 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset)); 1076 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset));
1053 if (!Marking::MarkBitFrom(code).Get()) continue; 1077 if (Marking::IsWhite(Marking::MarkBitFrom(code))) continue;
1054 1078 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(code)));
1055 // Move every slot in the entry. 1079 // Move every slot in the entry.
1056 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) { 1080 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) {
1057 int dst_index = new_length++; 1081 int dst_index = new_length++;
1058 Object** slot = code_map->RawFieldOfElementAt(dst_index); 1082 Object** slot = code_map->RawFieldOfElementAt(dst_index);
1059 Object* object = code_map->get(i + j); 1083 Object* object = code_map->get(i + j);
1060 code_map->set(dst_index, object); 1084 code_map->set(dst_index, object);
1061 if (j == SharedFunctionInfo::kOsrAstIdOffset) { 1085 if (j == SharedFunctionInfo::kOsrAstIdOffset) {
1062 DCHECK(object->IsSmi()); 1086 DCHECK(object->IsSmi());
1063 } else { 1087 } else {
1064 DCHECK( 1088 DCHECK(
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 // Marks the object black and pushes it on the marking stack. 1344 // Marks the object black and pushes it on the marking stack.
1321 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { 1345 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
1322 MarkBit mark = Marking::MarkBitFrom(object); 1346 MarkBit mark = Marking::MarkBitFrom(object);
1323 heap->mark_compact_collector()->MarkObject(object, mark); 1347 heap->mark_compact_collector()->MarkObject(object, mark);
1324 } 1348 }
1325 1349
1326 // Marks the object black without pushing it on the marking stack. 1350 // Marks the object black without pushing it on the marking stack.
1327 // Returns true if object needed marking and false otherwise. 1351 // Returns true if object needed marking and false otherwise.
1328 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { 1352 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
1329 MarkBit mark_bit = Marking::MarkBitFrom(object); 1353 MarkBit mark_bit = Marking::MarkBitFrom(object);
1330 if (!mark_bit.Get()) { 1354 if (Marking::IsWhite(mark_bit)) {
1331 heap->mark_compact_collector()->SetMark(object, mark_bit); 1355 heap->mark_compact_collector()->SetMark(object, mark_bit);
1332 return true; 1356 return true;
1333 } 1357 }
1334 return false; 1358 return false;
1335 } 1359 }
1336 1360
1337 // Mark object pointed to by p. 1361 // Mark object pointed to by p.
1338 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 1362 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector,
1339 Object** anchor_slot, Object** p)) { 1363 Object** anchor_slot, Object** p)) {
1340 if (!(*p)->IsHeapObject()) return; 1364 if (!(*p)->IsHeapObject()) return;
(...skipping 30 matching lines...) Expand all
1371 if (check.HasOverflowed()) return false; 1395 if (check.HasOverflowed()) return false;
1372 1396
1373 MarkCompactCollector* collector = heap->mark_compact_collector(); 1397 MarkCompactCollector* collector = heap->mark_compact_collector();
1374 // Visit the unmarked objects. 1398 // Visit the unmarked objects.
1375 for (Object** p = start; p < end; p++) { 1399 for (Object** p = start; p < end; p++) {
1376 Object* o = *p; 1400 Object* o = *p;
1377 if (!o->IsHeapObject()) continue; 1401 if (!o->IsHeapObject()) continue;
1378 collector->RecordSlot(start, p, o); 1402 collector->RecordSlot(start, p, o);
1379 HeapObject* obj = HeapObject::cast(o); 1403 HeapObject* obj = HeapObject::cast(o);
1380 MarkBit mark = Marking::MarkBitFrom(obj); 1404 MarkBit mark = Marking::MarkBitFrom(obj);
1381 if (mark.Get()) continue; 1405 if (Marking::IsBlackOrGrey(mark)) continue;
1382 VisitUnmarkedObject(collector, obj); 1406 VisitUnmarkedObject(collector, obj);
1383 } 1407 }
1384 return true; 1408 return true;
1385 } 1409 }
1386 1410
1387 private: 1411 private:
1388 template <int id> 1412 template <int id>
1389 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); 1413 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
1390 1414
1391 // Code flushing support. 1415 // Code flushing support.
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 // ProcessTopOptimizedFrame. 1740 // ProcessTopOptimizedFrame.
1717 void VisitNextCodeLink(Object** p) {} 1741 void VisitNextCodeLink(Object** p) {}
1718 1742
1719 private: 1743 private:
1720 void MarkObjectByPointer(Object** p) { 1744 void MarkObjectByPointer(Object** p) {
1721 if (!(*p)->IsHeapObject()) return; 1745 if (!(*p)->IsHeapObject()) return;
1722 1746
1723 // Replace flat cons strings in place. 1747 // Replace flat cons strings in place.
1724 HeapObject* object = ShortCircuitConsString(p); 1748 HeapObject* object = ShortCircuitConsString(p);
1725 MarkBit mark_bit = Marking::MarkBitFrom(object); 1749 MarkBit mark_bit = Marking::MarkBitFrom(object);
1726 if (mark_bit.Get()) return; 1750 if (Marking::IsBlackOrGrey(mark_bit)) return;
1727 1751
1728 Map* map = object->map(); 1752 Map* map = object->map();
1729 // Mark the object. 1753 // Mark the object.
1730 collector_->SetMark(object, mark_bit); 1754 collector_->SetMark(object, mark_bit);
1731 1755
1732 // Mark the map pointer and body, and push them on the marking stack. 1756 // Mark the map pointer and body, and push them on the marking stack.
1733 MarkBit map_mark = Marking::MarkBitFrom(map); 1757 MarkBit map_mark = Marking::MarkBitFrom(map);
1734 collector_->MarkObject(map, map_mark); 1758 collector_->MarkObject(map, map_mark);
1735 MarkCompactMarkingVisitor::IterateBody(map, object); 1759 MarkCompactMarkingVisitor::IterateBody(map, object);
1736 1760
(...skipping 10 matching lines...) Expand all
1747 template <bool finalize_external_strings> 1771 template <bool finalize_external_strings>
1748 class StringTableCleaner : public ObjectVisitor { 1772 class StringTableCleaner : public ObjectVisitor {
1749 public: 1773 public:
1750 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {} 1774 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {}
1751 1775
1752 virtual void VisitPointers(Object** start, Object** end) { 1776 virtual void VisitPointers(Object** start, Object** end) {
1753 // Visit all HeapObject pointers in [start, end). 1777 // Visit all HeapObject pointers in [start, end).
1754 for (Object** p = start; p < end; p++) { 1778 for (Object** p = start; p < end; p++) {
1755 Object* o = *p; 1779 Object* o = *p;
1756 if (o->IsHeapObject() && 1780 if (o->IsHeapObject() &&
1757 !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { 1781 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(o)))) {
1758 if (finalize_external_strings) { 1782 if (finalize_external_strings) {
1759 DCHECK(o->IsExternalString()); 1783 DCHECK(o->IsExternalString());
1760 heap_->FinalizeExternalString(String::cast(*p)); 1784 heap_->FinalizeExternalString(String::cast(*p));
1761 } else { 1785 } else {
1762 pointers_removed_++; 1786 pointers_removed_++;
1763 } 1787 }
1764 // Set the entry to the_hole_value (as deleted). 1788 // Set the entry to the_hole_value (as deleted).
1765 *p = heap_->the_hole_value(); 1789 *p = heap_->the_hole_value();
1766 } 1790 }
1767 } 1791 }
(...skipping 12 matching lines...) Expand all
1780 1804
1781 typedef StringTableCleaner<false> InternalizedStringTableCleaner; 1805 typedef StringTableCleaner<false> InternalizedStringTableCleaner;
1782 typedef StringTableCleaner<true> ExternalStringTableCleaner; 1806 typedef StringTableCleaner<true> ExternalStringTableCleaner;
1783 1807
1784 1808
1785 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1809 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
1786 // are retained. 1810 // are retained.
1787 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1811 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
1788 public: 1812 public:
1789 virtual Object* RetainAs(Object* object) { 1813 virtual Object* RetainAs(Object* object) {
1790 if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { 1814 if (Marking::IsBlackOrGrey(
1815 Marking::MarkBitFrom(HeapObject::cast(object)))) {
1791 return object; 1816 return object;
1792 } else if (object->IsAllocationSite() && 1817 } else if (object->IsAllocationSite() &&
1793 !(AllocationSite::cast(object)->IsZombie())) { 1818 !(AllocationSite::cast(object)->IsZombie())) {
1794 // "dead" AllocationSites need to live long enough for a traversal of new 1819 // "dead" AllocationSites need to live long enough for a traversal of new
1795 // space. These sites get a one-time reprieve. 1820 // space. These sites get a one-time reprieve.
1796 AllocationSite* site = AllocationSite::cast(object); 1821 AllocationSite* site = AllocationSite::cast(object);
1797 site->MarkZombie(); 1822 site->MarkZombie();
1798 site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site); 1823 site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site);
1799 return object; 1824 return object;
1800 } else { 1825 } else {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 MarkBit::CellType current_cell = *cell; 1919 MarkBit::CellType current_cell = *cell;
1895 if (current_cell == 0) continue; 1920 if (current_cell == 0) continue;
1896 1921
1897 int offset = 0; 1922 int offset = 0;
1898 while (current_cell != 0) { 1923 while (current_cell != 0) {
1899 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); 1924 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
1900 current_cell >>= trailing_zeros; 1925 current_cell >>= trailing_zeros;
1901 offset += trailing_zeros; 1926 offset += trailing_zeros;
1902 Address address = cell_base + offset * kPointerSize; 1927 Address address = cell_base + offset * kPointerSize;
1903 HeapObject* object = HeapObject::FromAddress(address); 1928 HeapObject* object = HeapObject::FromAddress(address);
1929 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
1904 1930
1905 int size = object->Size(); 1931 int size = object->Size();
1906 survivors_size += size; 1932 survivors_size += size;
1907 1933
1908 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); 1934 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT);
1909 1935
1910 offset++; 1936 offset += 2;
1911 current_cell >>= 1; 1937 current_cell >>= 2;
1912 1938
1913 // TODO(hpayer): Refactor EvacuateObject and call this function instead. 1939 // TODO(hpayer): Refactor EvacuateObject and call this function instead.
1914 if (heap()->ShouldBePromoted(object->address(), size) && 1940 if (heap()->ShouldBePromoted(object->address(), size) &&
1915 TryPromoteObject(object, size)) { 1941 TryPromoteObject(object, size)) {
1916 continue; 1942 continue;
1917 } 1943 }
1918 1944
1919 AllocationResult allocation = new_space->AllocateRaw(size); 1945 AllocationResult allocation = new_space->AllocateRaw(size);
1920 if (allocation.IsRetry()) { 1946 if (allocation.IsRetry()) {
1921 if (!new_space->AddFreshPage()) { 1947 if (!new_space->AddFreshPage()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 if (marking_deque->IsFull()) return; 1985 if (marking_deque->IsFull()) return;
1960 } 1986 }
1961 } 1987 }
1962 1988
1963 1989
1964 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1990 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1965 Object* o = *p; 1991 Object* o = *p;
1966 if (!o->IsHeapObject()) return false; 1992 if (!o->IsHeapObject()) return false;
1967 HeapObject* heap_object = HeapObject::cast(o); 1993 HeapObject* heap_object = HeapObject::cast(o);
1968 MarkBit mark = Marking::MarkBitFrom(heap_object); 1994 MarkBit mark = Marking::MarkBitFrom(heap_object);
1969 return !mark.Get(); 1995 return Marking::IsWhite(mark);
1970 } 1996 }
1971 1997
1972 1998
1973 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, 1999 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
1974 Object** p) { 2000 Object** p) {
1975 Object* o = *p; 2001 Object* o = *p;
1976 DCHECK(o->IsHeapObject()); 2002 DCHECK(o->IsHeapObject());
1977 HeapObject* heap_object = HeapObject::cast(o); 2003 HeapObject* heap_object = HeapObject::cast(o);
1978 MarkBit mark = Marking::MarkBitFrom(heap_object); 2004 MarkBit mark = Marking::MarkBitFrom(heap_object);
1979 return !mark.Get(); 2005 return Marking::IsWhite(mark);
1980 } 2006 }
1981 2007
1982 2008
1983 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { 2009 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
1984 StringTable* string_table = heap()->string_table(); 2010 StringTable* string_table = heap()->string_table();
1985 // Mark the string table itself. 2011 // Mark the string table itself.
1986 MarkBit string_table_mark = Marking::MarkBitFrom(string_table); 2012 MarkBit string_table_mark = Marking::MarkBitFrom(string_table);
1987 if (!string_table_mark.Get()) { 2013 if (Marking::IsWhite(string_table_mark)) {
1988 // String table could have already been marked by visiting the handles list. 2014 // String table could have already been marked by visiting the handles list.
1989 SetMark(string_table, string_table_mark); 2015 SetMark(string_table, string_table_mark);
1990 } 2016 }
1991 // Explicitly mark the prefix. 2017 // Explicitly mark the prefix.
1992 string_table->IteratePrefix(visitor); 2018 string_table->IteratePrefix(visitor);
1993 ProcessMarkingDeque(); 2019 ProcessMarkingDeque();
1994 } 2020 }
1995 2021
1996 2022
1997 void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) { 2023 void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 int length = retained_maps->Length(); 2193 int length = retained_maps->Length();
2168 int new_length = 0; 2194 int new_length = 0;
2169 for (int i = 0; i < length; i += 2) { 2195 for (int i = 0; i < length; i += 2) {
2170 DCHECK(retained_maps->Get(i)->IsWeakCell()); 2196 DCHECK(retained_maps->Get(i)->IsWeakCell());
2171 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); 2197 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
2172 if (cell->cleared()) continue; 2198 if (cell->cleared()) continue;
2173 int age = Smi::cast(retained_maps->Get(i + 1))->value(); 2199 int age = Smi::cast(retained_maps->Get(i + 1))->value();
2174 int new_age; 2200 int new_age;
2175 Map* map = Map::cast(cell->value()); 2201 Map* map = Map::cast(cell->value());
2176 MarkBit map_mark = Marking::MarkBitFrom(map); 2202 MarkBit map_mark = Marking::MarkBitFrom(map);
2177 if (!map_mark.Get()) { 2203 if (Marking::IsWhite(map_mark)) {
2178 if (age == 0) { 2204 if (age == 0) {
2179 // The map has aged. Do not retain this map. 2205 // The map has aged. Do not retain this map.
2180 continue; 2206 continue;
2181 } 2207 }
2182 Object* constructor = map->GetConstructor(); 2208 Object* constructor = map->GetConstructor();
2183 if (!constructor->IsHeapObject() || 2209 if (!constructor->IsHeapObject() || Marking::IsWhite(Marking::MarkBitFrom(
2184 !Marking::MarkBitFrom(HeapObject::cast(constructor)).Get()) { 2210 HeapObject::cast(constructor)))) {
2185 // The constructor is dead, no new objects with this map can 2211 // The constructor is dead, no new objects with this map can
2186 // be created. Do not retain this map. 2212 // be created. Do not retain this map.
2187 continue; 2213 continue;
2188 } 2214 }
2189 Object* prototype = map->prototype(); 2215 Object* prototype = map->prototype();
2190 if (prototype->IsHeapObject() && 2216 if (prototype->IsHeapObject() &&
2191 !Marking::MarkBitFrom(HeapObject::cast(prototype)).Get()) { 2217 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) {
2192 // The prototype is not marked, age the map. 2218 // The prototype is not marked, age the map.
2193 new_age = age - 1; 2219 new_age = age - 1;
2194 } else { 2220 } else {
2195 // The prototype and the constructor are marked, this map keeps only 2221 // The prototype and the constructor are marked, this map keeps only
2196 // transition tree alive, not JSObjects. Do not age the map. 2222 // transition tree alive, not JSObjects. Do not age the map.
2197 new_age = age; 2223 new_age = age;
2198 } 2224 }
2199 MarkObject(map, map_mark); 2225 MarkObject(map, map_mark);
2200 } else { 2226 } else {
2201 new_age = FLAG_retain_maps_for_n_gc; 2227 new_age = FLAG_retain_maps_for_n_gc;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2395 for (HeapObject* obj = map_iterator.Next(); obj != NULL; 2421 for (HeapObject* obj = map_iterator.Next(); obj != NULL;
2396 obj = map_iterator.Next()) { 2422 obj = map_iterator.Next()) {
2397 Map* map = Map::cast(obj); 2423 Map* map = Map::cast(obj);
2398 2424
2399 if (!map->CanTransition()) continue; 2425 if (!map->CanTransition()) continue;
2400 2426
2401 MarkBit map_mark = Marking::MarkBitFrom(map); 2427 MarkBit map_mark = Marking::MarkBitFrom(map);
2402 ClearNonLivePrototypeTransitions(map); 2428 ClearNonLivePrototypeTransitions(map);
2403 ClearNonLiveMapTransitions(map, map_mark); 2429 ClearNonLiveMapTransitions(map, map_mark);
2404 2430
2405 if (!map_mark.Get()) { 2431 if (Marking::IsWhite(map_mark)) {
2406 have_code_to_deoptimize_ |= 2432 have_code_to_deoptimize_ |=
2407 map->dependent_code()->MarkCodeForDeoptimization( 2433 map->dependent_code()->MarkCodeForDeoptimization(
2408 isolate(), DependentCode::kWeakCodeGroup); 2434 isolate(), DependentCode::kWeakCodeGroup);
2409 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); 2435 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2410 } 2436 }
2411 } 2437 }
2412 2438
2413 WeakHashTable* table = heap_->weak_object_to_code_table(); 2439 WeakHashTable* table = heap_->weak_object_to_code_table();
2414 uint32_t capacity = table->Capacity(); 2440 uint32_t capacity = table->Capacity();
2415 for (uint32_t i = 0; i < capacity; i++) { 2441 for (uint32_t i = 0; i < capacity; i++) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2463 2489
2464 2490
2465 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, 2491 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
2466 MarkBit map_mark) { 2492 MarkBit map_mark) {
2467 Object* potential_parent = map->GetBackPointer(); 2493 Object* potential_parent = map->GetBackPointer();
2468 if (!potential_parent->IsMap()) return; 2494 if (!potential_parent->IsMap()) return;
2469 Map* parent = Map::cast(potential_parent); 2495 Map* parent = Map::cast(potential_parent);
2470 2496
2471 // Follow back pointer, check whether we are dealing with a map transition 2497 // Follow back pointer, check whether we are dealing with a map transition
2472 // from a live map to a dead path and in case clear transitions of parent. 2498 // from a live map to a dead path and in case clear transitions of parent.
2473 bool current_is_alive = map_mark.Get(); 2499 bool current_is_alive = Marking::IsBlackOrGrey(map_mark);
2474 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2500 bool parent_is_alive = Marking::IsBlackOrGrey(Marking::MarkBitFrom(parent));
2475 if (!current_is_alive && parent_is_alive) { 2501 if (!current_is_alive && parent_is_alive) {
2476 ClearMapTransitions(parent, map); 2502 ClearMapTransitions(parent, map);
2477 } 2503 }
2478 } 2504 }
2479 2505
2480 2506
2481 // Clear a possible back pointer in case the transition leads to a dead map. 2507 // Clear a possible back pointer in case the transition leads to a dead map.
2482 // Return true in case a back pointer has been cleared and false otherwise. 2508 // Return true in case a back pointer has been cleared and false otherwise.
2483 bool MarkCompactCollector::ClearMapBackPointer(Map* target) { 2509 bool MarkCompactCollector::ClearMapBackPointer(Map* target) {
2484 if (Marking::MarkBitFrom(target).Get()) return false; 2510 if (Marking::IsBlackOrGrey(Marking::MarkBitFrom(target))) return false;
2485 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER); 2511 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER);
2486 return true; 2512 return true;
2487 } 2513 }
2488 2514
2489 2515
2490 void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) { 2516 void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) {
2491 Object* transitions = map->raw_transitions(); 2517 Object* transitions = map->raw_transitions();
2492 int num_transitions = TransitionArray::NumberOfTransitions(transitions); 2518 int num_transitions = TransitionArray::NumberOfTransitions(transitions);
2493 2519
2494 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 2520 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
3543 return false; 3569 return false;
3544 } 3570 }
3545 3571
3546 Address code_start = code->address(); 3572 Address code_start = code->address();
3547 Address code_end = code_start + code->Size(); 3573 Address code_end = code_start + code->Size();
3548 3574
3549 uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start); 3575 uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start);
3550 uint32_t end_index = 3576 uint32_t end_index =
3551 MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize); 3577 MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize);
3552 3578
3579 // TODO(hpayer): Filter out invalidated code in
3580 // ClearInvalidSlotsBufferEntries.
3553 Bitmap* b = p->markbits(); 3581 Bitmap* b = p->markbits();
3554 3582
3555 MarkBit start_mark_bit = b->MarkBitFromIndex(start_index); 3583 MarkBit start_mark_bit = b->MarkBitFromIndex(start_index);
3556 MarkBit end_mark_bit = b->MarkBitFromIndex(end_index); 3584 MarkBit end_mark_bit = b->MarkBitFromIndex(end_index);
3557 3585
3558 MarkBit::CellType* start_cell = start_mark_bit.cell();
3559 MarkBit::CellType* end_cell = end_mark_bit.cell();
3560
3561 if (value) { 3586 if (value) {
3562 MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1); 3587 Marking::SetAllMarkBitsInRange(start_mark_bit, end_mark_bit);
3563 MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1;
3564
3565 if (start_cell == end_cell) {
3566 *start_cell |= start_mask & end_mask;
3567 } else {
3568 *start_cell |= start_mask;
3569 for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) {
3570 *cell = ~0;
3571 }
3572 *end_cell |= end_mask;
3573 }
3574 } else { 3588 } else {
3575 for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) { 3589 Marking::ClearAllMarkBitsOfCellsContainedInRange(start_mark_bit,
3576 *cell = 0; 3590 end_mark_bit);
3577 }
3578 } 3591 }
3579 3592
3580 return true; 3593 return true;
3581 } 3594 }
3582 3595
3583 3596
3584 static bool IsOnInvalidatedCodeObject(Address addr) { 3597 static bool IsOnInvalidatedCodeObject(Address addr) {
3585 // We did not record any slots in large objects thus 3598 // We did not record any slots in large objects thus
3586 // we can safely go to the page from the slot address. 3599 // we can safely go to the page from the slot address.
3587 Page* p = Page::FromAddress(addr); 3600 Page* p = Page::FromAddress(addr);
3588 3601
3589 // First check owner's identity because old space is swept concurrently or 3602 // First check owner's identity because old space is swept concurrently or
3590 // lazily and might still have non-zero mark-bits on some pages. 3603 // lazily and might still have non-zero mark-bits on some pages.
3591 if (p->owner()->identity() != CODE_SPACE) return false; 3604 if (p->owner()->identity() != CODE_SPACE) return false;
3592 3605
3593 // In code space only bits on evacuation candidates (but we don't record 3606 // In code space only bits on evacuation candidates (but we don't record
3594 // any slots on them) and under invalidated code objects are non-zero. 3607 // any slots on them) and under invalidated code objects are non-zero.
3595 MarkBit mark_bit = 3608 MarkBit mark_bit =
3596 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 3609 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr));
3597 3610
3598 return mark_bit.Get(); 3611 return Marking::IsBlackOrGrey(mark_bit);
3599 } 3612 }
3600 3613
3601 3614
3602 void MarkCompactCollector::InvalidateCode(Code* code) { 3615 void MarkCompactCollector::InvalidateCode(Code* code) {
3603 if (heap_->incremental_marking()->IsCompacting() && 3616 if (heap_->incremental_marking()->IsCompacting() &&
3604 !ShouldSkipEvacuationSlotRecording(code)) { 3617 !ShouldSkipEvacuationSlotRecording(code)) {
3605 DCHECK(compacting_); 3618 DCHECK(compacting_);
3606 3619
3607 // If the object is white than no slots were recorded on it yet. 3620 // If the object is white than no slots were recorded on it yet.
3608 MarkBit mark_bit = Marking::MarkBitFrom(code); 3621 MarkBit mark_bit = Marking::MarkBitFrom(code);
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4751 SlotsBuffer* buffer = *buffer_address; 4764 SlotsBuffer* buffer = *buffer_address;
4752 while (buffer != NULL) { 4765 while (buffer != NULL) {
4753 SlotsBuffer* next_buffer = buffer->next(); 4766 SlotsBuffer* next_buffer = buffer->next();
4754 DeallocateBuffer(buffer); 4767 DeallocateBuffer(buffer);
4755 buffer = next_buffer; 4768 buffer = next_buffer;
4756 } 4769 }
4757 *buffer_address = NULL; 4770 *buffer_address = NULL;
4758 } 4771 }
4759 } 4772 }
4760 } // namespace v8::internal 4773 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698