Chromium Code Reviews| 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/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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |