OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/spaces.h" | 5 #include "src/heap/spaces.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 chunk->old_to_old_slots_ = nullptr; | 531 chunk->old_to_old_slots_ = nullptr; |
532 chunk->typed_old_to_new_slots_.SetValue(nullptr); | 532 chunk->typed_old_to_new_slots_.SetValue(nullptr); |
533 chunk->typed_old_to_old_slots_ = nullptr; | 533 chunk->typed_old_to_old_slots_ = nullptr; |
534 chunk->skip_list_ = nullptr; | 534 chunk->skip_list_ = nullptr; |
535 chunk->progress_bar_ = 0; | 535 chunk->progress_bar_ = 0; |
536 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); | 536 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); |
537 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); | 537 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); |
538 chunk->mutex_ = new base::Mutex(); | 538 chunk->mutex_ = new base::Mutex(); |
539 chunk->available_in_free_list_ = 0; | 539 chunk->available_in_free_list_ = 0; |
540 chunk->wasted_memory_ = 0; | 540 chunk->wasted_memory_ = 0; |
541 chunk->ClearLiveness(); | |
542 chunk->young_generation_bitmap_ = nullptr; | 541 chunk->young_generation_bitmap_ = nullptr; |
543 chunk->set_next_chunk(nullptr); | 542 chunk->set_next_chunk(nullptr); |
544 chunk->set_prev_chunk(nullptr); | 543 chunk->set_prev_chunk(nullptr); |
545 chunk->local_tracker_ = nullptr; | 544 chunk->local_tracker_ = nullptr; |
546 | 545 |
| 546 MarkingState::Internal(chunk).ClearLiveness(); |
| 547 |
547 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 548 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
548 | 549 |
549 if (executable == EXECUTABLE) { | 550 if (executable == EXECUTABLE) { |
550 chunk->SetFlag(IS_EXECUTABLE); | 551 chunk->SetFlag(IS_EXECUTABLE); |
551 } | 552 } |
552 | 553 |
553 if (reservation != nullptr) { | 554 if (reservation != nullptr) { |
554 chunk->reservation_.TakeControl(reservation); | 555 chunk->reservation_.TakeControl(reservation); |
555 } | 556 } |
556 | 557 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 CHECK_EQ(filler->address() + filler->Size(), area_end()); | 848 CHECK_EQ(filler->address() + filler->Size(), area_end()); |
848 } | 849 } |
849 return unused; | 850 return unused; |
850 } | 851 } |
851 | 852 |
852 void Page::CreateBlackArea(Address start, Address end) { | 853 void Page::CreateBlackArea(Address start, Address end) { |
853 DCHECK(heap()->incremental_marking()->black_allocation()); | 854 DCHECK(heap()->incremental_marking()->black_allocation()); |
854 DCHECK_EQ(Page::FromAddress(start), this); | 855 DCHECK_EQ(Page::FromAddress(start), this); |
855 DCHECK_NE(start, end); | 856 DCHECK_NE(start, end); |
856 DCHECK_EQ(Page::FromAddress(end - 1), this); | 857 DCHECK_EQ(Page::FromAddress(end - 1), this); |
857 markbits()->SetRange(AddressToMarkbitIndex(start), | 858 MarkingState::Internal(this).bitmap()->SetRange(AddressToMarkbitIndex(start), |
858 AddressToMarkbitIndex(end)); | 859 AddressToMarkbitIndex(end)); |
859 IncrementLiveBytes(static_cast<int>(end - start)); | 860 MarkingState::Internal(this).IncrementLiveBytes( |
| 861 static_cast<int>(end - start)); |
860 } | 862 } |
861 | 863 |
862 void MemoryAllocator::PartialFreeMemory(MemoryChunk* chunk, | 864 void MemoryAllocator::PartialFreeMemory(MemoryChunk* chunk, |
863 Address start_free) { | 865 Address start_free) { |
864 // We do not allow partial shrink for code. | 866 // We do not allow partial shrink for code. |
865 DCHECK(chunk->executable() == NOT_EXECUTABLE); | 867 DCHECK(chunk->executable() == NOT_EXECUTABLE); |
866 | 868 |
867 intptr_t size; | 869 intptr_t size; |
868 base::VirtualMemory* reservation = chunk->reserved_memory(); | 870 base::VirtualMemory* reservation = chunk->reserved_memory(); |
869 DCHECK(reservation->IsReserved()); | 871 DCHECK(reservation->IsReserved()); |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 DCHECK_NULL(young_generation_bitmap_); | 1191 DCHECK_NULL(young_generation_bitmap_); |
1190 young_generation_bitmap_ = static_cast<Bitmap*>(calloc(1, Bitmap::kSize)); | 1192 young_generation_bitmap_ = static_cast<Bitmap*>(calloc(1, Bitmap::kSize)); |
1191 } | 1193 } |
1192 | 1194 |
1193 void MemoryChunk::ReleaseYoungGenerationBitmap() { | 1195 void MemoryChunk::ReleaseYoungGenerationBitmap() { |
1194 DCHECK_NOT_NULL(young_generation_bitmap_); | 1196 DCHECK_NOT_NULL(young_generation_bitmap_); |
1195 free(young_generation_bitmap_); | 1197 free(young_generation_bitmap_); |
1196 young_generation_bitmap_ = nullptr; | 1198 young_generation_bitmap_ = nullptr; |
1197 } | 1199 } |
1198 | 1200 |
1199 template <MarkingMode mode> | |
1200 void MemoryChunk::ClearLiveness() { | |
1201 markbits<mode>()->Clear(); | |
1202 ResetLiveBytes<mode>(); | |
1203 } | |
1204 | |
1205 template void MemoryChunk::ClearLiveness<MarkingMode::FULL>(); | |
1206 template void MemoryChunk::ClearLiveness<MarkingMode::YOUNG_GENERATION>(); | |
1207 | |
1208 // ----------------------------------------------------------------------------- | 1201 // ----------------------------------------------------------------------------- |
1209 // PagedSpace implementation | 1202 // PagedSpace implementation |
1210 | 1203 |
1211 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == | 1204 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == |
1212 ObjectSpace::kObjectSpaceNewSpace); | 1205 ObjectSpace::kObjectSpaceNewSpace); |
1213 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == | 1206 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == |
1214 ObjectSpace::kObjectSpaceOldSpace); | 1207 ObjectSpace::kObjectSpaceOldSpace); |
1215 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) == | 1208 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) == |
1216 ObjectSpace::kObjectSpaceCodeSpace); | 1209 ObjectSpace::kObjectSpaceCodeSpace); |
1217 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) == | 1210 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) == |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 if (current_top == nullptr) { | 1406 if (current_top == nullptr) { |
1414 DCHECK(current_limit == nullptr); | 1407 DCHECK(current_limit == nullptr); |
1415 return; | 1408 return; |
1416 } | 1409 } |
1417 | 1410 |
1418 if (heap()->incremental_marking()->black_allocation()) { | 1411 if (heap()->incremental_marking()->black_allocation()) { |
1419 Page* page = Page::FromAllocationAreaAddress(current_top); | 1412 Page* page = Page::FromAllocationAreaAddress(current_top); |
1420 | 1413 |
1421 // Clear the bits in the unused black area. | 1414 // Clear the bits in the unused black area. |
1422 if (current_top != current_limit) { | 1415 if (current_top != current_limit) { |
1423 page->markbits()->ClearRange(page->AddressToMarkbitIndex(current_top), | 1416 MarkingState::Internal(page).bitmap()->ClearRange( |
1424 page->AddressToMarkbitIndex(current_limit)); | 1417 page->AddressToMarkbitIndex(current_top), |
1425 page->IncrementLiveBytes(-static_cast<int>(current_limit - current_top)); | 1418 page->AddressToMarkbitIndex(current_limit)); |
| 1419 MarkingState::Internal(page).IncrementLiveBytes( |
| 1420 -static_cast<int>(current_limit - current_top)); |
1426 } | 1421 } |
1427 } | 1422 } |
1428 | 1423 |
1429 SetTopAndLimit(NULL, NULL); | 1424 SetTopAndLimit(NULL, NULL); |
1430 DCHECK_GE(current_limit, current_top); | 1425 DCHECK_GE(current_limit, current_top); |
1431 Free(current_top, current_limit - current_top); | 1426 Free(current_top, current_limit - current_top); |
1432 } | 1427 } |
1433 | 1428 |
1434 void PagedSpace::IncreaseCapacity(size_t bytes) { | 1429 void PagedSpace::IncreaseCapacity(size_t bytes) { |
1435 accounting_stats_.ExpandSpace(bytes); | 1430 accounting_stats_.ExpandSpace(bytes); |
1436 } | 1431 } |
1437 | 1432 |
1438 void PagedSpace::ReleasePage(Page* page) { | 1433 void PagedSpace::ReleasePage(Page* page) { |
1439 DCHECK_EQ(page->LiveBytes(), 0); | 1434 DCHECK_EQ(0, MarkingState::Internal(page).live_bytes()); |
1440 DCHECK_EQ(page->owner(), this); | 1435 DCHECK_EQ(page->owner(), this); |
1441 | 1436 |
1442 free_list_.EvictFreeListItems(page); | 1437 free_list_.EvictFreeListItems(page); |
1443 DCHECK(!free_list_.ContainsPageFreeListItems(page)); | 1438 DCHECK(!free_list_.ContainsPageFreeListItems(page)); |
1444 | 1439 |
1445 if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { | 1440 if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { |
1446 allocation_info_.Reset(nullptr, nullptr); | 1441 allocation_info_.Reset(nullptr, nullptr); |
1447 } | 1442 } |
1448 | 1443 |
1449 // If page is still in a list, unlink it from that list. | 1444 // If page is still in a list, unlink it from that list. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 | 1485 |
1491 // Perform space-specific object verification. | 1486 // Perform space-specific object verification. |
1492 VerifyObject(object); | 1487 VerifyObject(object); |
1493 | 1488 |
1494 // The object itself should look OK. | 1489 // The object itself should look OK. |
1495 object->ObjectVerify(); | 1490 object->ObjectVerify(); |
1496 | 1491 |
1497 // All the interior pointers should be contained in the heap. | 1492 // All the interior pointers should be contained in the heap. |
1498 int size = object->Size(); | 1493 int size = object->Size(); |
1499 object->IterateBody(map->instance_type(), size, visitor); | 1494 object->IterateBody(map->instance_type(), size, visitor); |
1500 if (ObjectMarking::IsBlack(object)) { | 1495 if (ObjectMarking::IsBlack(object, MarkingState::Internal(object))) { |
1501 black_size += size; | 1496 black_size += size; |
1502 } | 1497 } |
1503 | 1498 |
1504 CHECK(object->address() + size <= top); | 1499 CHECK(object->address() + size <= top); |
1505 end_of_previous_object = object->address() + size; | 1500 end_of_previous_object = object->address() + size; |
1506 } | 1501 } |
1507 CHECK_LE(black_size, page->LiveBytes()); | 1502 CHECK_LE(black_size, MarkingState::Internal(page).live_bytes()); |
1508 } | 1503 } |
1509 CHECK(allocation_pointer_found_in_space); | 1504 CHECK(allocation_pointer_found_in_space); |
1510 } | 1505 } |
1511 #endif // VERIFY_HEAP | 1506 #endif // VERIFY_HEAP |
1512 | 1507 |
1513 // ----------------------------------------------------------------------------- | 1508 // ----------------------------------------------------------------------------- |
1514 // NewSpace implementation | 1509 // NewSpace implementation |
1515 | 1510 |
1516 bool NewSpace::SetUp(size_t initial_semispace_capacity, | 1511 bool NewSpace::SetUp(size_t initial_semispace_capacity, |
1517 size_t maximum_semispace_capacity) { | 1512 size_t maximum_semispace_capacity) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 } | 1625 } |
1631 } | 1626 } |
1632 while (actual_pages < expected_pages) { | 1627 while (actual_pages < expected_pages) { |
1633 actual_pages++; | 1628 actual_pages++; |
1634 current_page = | 1629 current_page = |
1635 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( | 1630 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
1636 Page::kAllocatableMemory, this, executable()); | 1631 Page::kAllocatableMemory, this, executable()); |
1637 if (current_page == nullptr) return false; | 1632 if (current_page == nullptr) return false; |
1638 DCHECK_NOT_NULL(current_page); | 1633 DCHECK_NOT_NULL(current_page); |
1639 current_page->InsertAfter(anchor()); | 1634 current_page->InsertAfter(anchor()); |
1640 current_page->ClearLiveness(); | 1635 MarkingState::Internal(current_page).ClearLiveness(); |
1641 current_page->SetFlags(anchor()->prev_page()->GetFlags(), | 1636 current_page->SetFlags(anchor()->prev_page()->GetFlags(), |
1642 static_cast<uintptr_t>(Page::kCopyAllFlags)); | 1637 static_cast<uintptr_t>(Page::kCopyAllFlags)); |
1643 heap()->CreateFillerObjectAt(current_page->area_start(), | 1638 heap()->CreateFillerObjectAt(current_page->area_start(), |
1644 static_cast<int>(current_page->area_size()), | 1639 static_cast<int>(current_page->area_size()), |
1645 ClearRecordedSlots::kNo); | 1640 ClearRecordedSlots::kNo); |
1646 } | 1641 } |
1647 } | 1642 } |
1648 return true; | 1643 return true; |
1649 } | 1644 } |
1650 | 1645 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1697 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1703 } | 1698 } |
1704 | 1699 |
1705 | 1700 |
1706 void NewSpace::ResetAllocationInfo() { | 1701 void NewSpace::ResetAllocationInfo() { |
1707 Address old_top = allocation_info_.top(); | 1702 Address old_top = allocation_info_.top(); |
1708 to_space_.Reset(); | 1703 to_space_.Reset(); |
1709 UpdateAllocationInfo(); | 1704 UpdateAllocationInfo(); |
1710 // Clear all mark-bits in the to-space. | 1705 // Clear all mark-bits in the to-space. |
1711 for (Page* p : to_space_) { | 1706 for (Page* p : to_space_) { |
1712 p->ClearLiveness(); | 1707 MarkingState::Internal(p).ClearLiveness(); |
1713 } | 1708 } |
1714 InlineAllocationStep(old_top, allocation_info_.top(), nullptr, 0); | 1709 InlineAllocationStep(old_top, allocation_info_.top(), nullptr, 0); |
1715 } | 1710 } |
1716 | 1711 |
1717 | 1712 |
1718 void NewSpace::UpdateInlineAllocationLimit(int size_in_bytes) { | 1713 void NewSpace::UpdateInlineAllocationLimit(int size_in_bytes) { |
1719 if (heap()->inline_allocation_disabled()) { | 1714 if (heap()->inline_allocation_disabled()) { |
1720 // Lowest limit when linear allocation was disabled. | 1715 // Lowest limit when linear allocation was disabled. |
1721 Address high = to_space_.page_high(); | 1716 Address high = to_space_.page_high(); |
1722 Address new_top = allocation_info_.top() + size_in_bytes; | 1717 Address new_top = allocation_info_.top() + size_in_bytes; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2003 DCHECK_NE(last_page, anchor()); | 1998 DCHECK_NE(last_page, anchor()); |
2004 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { | 1999 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { |
2005 Page* new_page = | 2000 Page* new_page = |
2006 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( | 2001 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
2007 Page::kAllocatableMemory, this, executable()); | 2002 Page::kAllocatableMemory, this, executable()); |
2008 if (new_page == nullptr) { | 2003 if (new_page == nullptr) { |
2009 RewindPages(last_page, pages_added); | 2004 RewindPages(last_page, pages_added); |
2010 return false; | 2005 return false; |
2011 } | 2006 } |
2012 new_page->InsertAfter(last_page); | 2007 new_page->InsertAfter(last_page); |
2013 new_page->ClearLiveness(); | 2008 MarkingState::Internal(new_page).ClearLiveness(); |
2014 // Duplicate the flags that was set on the old page. | 2009 // Duplicate the flags that was set on the old page. |
2015 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); | 2010 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); |
2016 last_page = new_page; | 2011 last_page = new_page; |
2017 } | 2012 } |
2018 AccountCommitted(delta); | 2013 AccountCommitted(delta); |
2019 current_capacity_ = new_capacity; | 2014 current_capacity_ = new_capacity; |
2020 return true; | 2015 return true; |
2021 } | 2016 } |
2022 | 2017 |
2023 void SemiSpace::RewindPages(Page* start, int num_pages) { | 2018 void SemiSpace::RewindPages(Page* start, int num_pages) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 anchor_.prev_page()->set_next_page(&anchor_); | 2059 anchor_.prev_page()->set_next_page(&anchor_); |
2065 anchor_.next_page()->set_prev_page(&anchor_); | 2060 anchor_.next_page()->set_prev_page(&anchor_); |
2066 | 2061 |
2067 for (Page* page : *this) { | 2062 for (Page* page : *this) { |
2068 page->set_owner(this); | 2063 page->set_owner(this); |
2069 page->SetFlags(flags, mask); | 2064 page->SetFlags(flags, mask); |
2070 if (id_ == kToSpace) { | 2065 if (id_ == kToSpace) { |
2071 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 2066 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
2072 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 2067 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
2073 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 2068 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
2074 page->ResetLiveBytes(); | 2069 MarkingState::Internal(page).SetLiveBytes(0); |
2075 } else { | 2070 } else { |
2076 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 2071 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
2077 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 2072 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
2078 } | 2073 } |
2079 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 2074 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
2080 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 2075 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
2081 } | 2076 } |
2082 } | 2077 } |
2083 | 2078 |
2084 | 2079 |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3037 } | 3032 } |
3038 | 3033 |
3039 heap()->StartIncrementalMarkingIfAllocationLimitIsReached(Heap::kNoGCFlags, | 3034 heap()->StartIncrementalMarkingIfAllocationLimitIsReached(Heap::kNoGCFlags, |
3040 kNoGCCallbackFlags); | 3035 kNoGCCallbackFlags); |
3041 AllocationStep(object->address(), object_size); | 3036 AllocationStep(object->address(), object_size); |
3042 | 3037 |
3043 heap()->CreateFillerObjectAt(object->address(), object_size, | 3038 heap()->CreateFillerObjectAt(object->address(), object_size, |
3044 ClearRecordedSlots::kNo); | 3039 ClearRecordedSlots::kNo); |
3045 | 3040 |
3046 if (heap()->incremental_marking()->black_allocation()) { | 3041 if (heap()->incremental_marking()->black_allocation()) { |
3047 ObjectMarking::WhiteToBlack(object); | 3042 ObjectMarking::WhiteToBlack(object, MarkingState::Internal(object)); |
3048 } | 3043 } |
3049 return object; | 3044 return object; |
3050 } | 3045 } |
3051 | 3046 |
3052 | 3047 |
3053 size_t LargeObjectSpace::CommittedPhysicalMemory() { | 3048 size_t LargeObjectSpace::CommittedPhysicalMemory() { |
3054 // On a platform that provides lazy committing of memory, we over-account | 3049 // On a platform that provides lazy committing of memory, we over-account |
3055 // the actually committed memory. There is no easy way right now to support | 3050 // the actually committed memory. There is no easy way right now to support |
3056 // precise accounting of committed memory in large object space. | 3051 // precise accounting of committed memory in large object space. |
3057 return CommittedMemory(); | 3052 return CommittedMemory(); |
(...skipping 26 matching lines...) Expand all Loading... |
3084 return page; | 3079 return page; |
3085 } | 3080 } |
3086 } | 3081 } |
3087 return NULL; | 3082 return NULL; |
3088 } | 3083 } |
3089 | 3084 |
3090 | 3085 |
3091 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { | 3086 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { |
3092 LargeObjectIterator it(this); | 3087 LargeObjectIterator it(this); |
3093 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 3088 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
3094 if (ObjectMarking::IsBlackOrGrey(obj)) { | 3089 if (ObjectMarking::IsBlackOrGrey(obj, MarkingState::Internal(obj))) { |
3095 Marking::MarkWhite(ObjectMarking::MarkBitFrom(obj)); | 3090 Marking::MarkWhite( |
| 3091 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj))); |
3096 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 3092 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
3097 chunk->ResetProgressBar(); | 3093 chunk->ResetProgressBar(); |
3098 chunk->ResetLiveBytes(); | 3094 MarkingState::Internal(chunk).SetLiveBytes(0); |
3099 } | 3095 } |
3100 DCHECK(ObjectMarking::IsWhite(obj)); | 3096 DCHECK(ObjectMarking::IsWhite(obj, MarkingState::Internal(obj))); |
3101 } | 3097 } |
3102 } | 3098 } |
3103 | 3099 |
3104 void LargeObjectSpace::InsertChunkMapEntries(LargePage* page) { | 3100 void LargeObjectSpace::InsertChunkMapEntries(LargePage* page) { |
3105 // Register all MemoryChunk::kAlignment-aligned chunks covered by | 3101 // Register all MemoryChunk::kAlignment-aligned chunks covered by |
3106 // this large page in the chunk map. | 3102 // this large page in the chunk map. |
3107 uintptr_t start = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment; | 3103 uintptr_t start = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment; |
3108 uintptr_t limit = (reinterpret_cast<uintptr_t>(page) + (page->size() - 1)) / | 3104 uintptr_t limit = (reinterpret_cast<uintptr_t>(page) + (page->size() - 1)) / |
3109 MemoryChunk::kAlignment; | 3105 MemoryChunk::kAlignment; |
3110 // There may be concurrent access on the chunk map. We have to take the lock | 3106 // There may be concurrent access on the chunk map. We have to take the lock |
(...skipping 21 matching lines...) Expand all Loading... |
3132 for (uintptr_t key = start; key <= limit; key++) { | 3128 for (uintptr_t key = start; key <= limit; key++) { |
3133 chunk_map_.Remove(reinterpret_cast<void*>(key), static_cast<uint32_t>(key)); | 3129 chunk_map_.Remove(reinterpret_cast<void*>(key), static_cast<uint32_t>(key)); |
3134 } | 3130 } |
3135 } | 3131 } |
3136 | 3132 |
3137 void LargeObjectSpace::FreeUnmarkedObjects() { | 3133 void LargeObjectSpace::FreeUnmarkedObjects() { |
3138 LargePage* previous = NULL; | 3134 LargePage* previous = NULL; |
3139 LargePage* current = first_page_; | 3135 LargePage* current = first_page_; |
3140 while (current != NULL) { | 3136 while (current != NULL) { |
3141 HeapObject* object = current->GetObject(); | 3137 HeapObject* object = current->GetObject(); |
3142 DCHECK(!ObjectMarking::IsGrey(object)); | 3138 DCHECK(!ObjectMarking::IsGrey(object, MarkingState::Internal(object))); |
3143 if (ObjectMarking::IsBlack(object)) { | 3139 if (ObjectMarking::IsBlack(object, MarkingState::Internal(object))) { |
3144 Address free_start; | 3140 Address free_start; |
3145 if ((free_start = current->GetAddressToShrink()) != 0) { | 3141 if ((free_start = current->GetAddressToShrink()) != 0) { |
3146 // TODO(hpayer): Perform partial free concurrently. | 3142 // TODO(hpayer): Perform partial free concurrently. |
3147 current->ClearOutOfLiveRangeSlots(free_start); | 3143 current->ClearOutOfLiveRangeSlots(free_start); |
3148 RemoveChunkMapEntries(current, free_start); | 3144 RemoveChunkMapEntries(current, free_start); |
3149 heap()->memory_allocator()->PartialFreeMemory(current, free_start); | 3145 heap()->memory_allocator()->PartialFreeMemory(current, free_start); |
3150 } | 3146 } |
3151 previous = current; | 3147 previous = current; |
3152 current = current->next_page(); | 3148 current = current->next_page(); |
3153 } else { | 3149 } else { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3269 | 3265 |
3270 void Page::Print() { | 3266 void Page::Print() { |
3271 // Make a best-effort to print the objects in the page. | 3267 // Make a best-effort to print the objects in the page. |
3272 PrintF("Page@%p in %s\n", static_cast<void*>(this->address()), | 3268 PrintF("Page@%p in %s\n", static_cast<void*>(this->address()), |
3273 AllocationSpaceName(this->owner()->identity())); | 3269 AllocationSpaceName(this->owner()->identity())); |
3274 printf(" --------------------------------------\n"); | 3270 printf(" --------------------------------------\n"); |
3275 HeapObjectIterator objects(this); | 3271 HeapObjectIterator objects(this); |
3276 unsigned mark_size = 0; | 3272 unsigned mark_size = 0; |
3277 for (HeapObject* object = objects.Next(); object != NULL; | 3273 for (HeapObject* object = objects.Next(); object != NULL; |
3278 object = objects.Next()) { | 3274 object = objects.Next()) { |
3279 bool is_marked = ObjectMarking::IsBlackOrGrey(object); | 3275 bool is_marked = |
| 3276 ObjectMarking::IsBlackOrGrey(object, MarkingState::Internal(object)); |
3280 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. | 3277 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. |
3281 if (is_marked) { | 3278 if (is_marked) { |
3282 mark_size += object->Size(); | 3279 mark_size += object->Size(); |
3283 } | 3280 } |
3284 object->ShortPrint(); | 3281 object->ShortPrint(); |
3285 PrintF("\n"); | 3282 PrintF("\n"); |
3286 } | 3283 } |
3287 printf(" --------------------------------------\n"); | 3284 printf(" --------------------------------------\n"); |
3288 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3285 printf(" Marked: %x, LiveCount: %" V8PRIdPTR "\n", mark_size, |
| 3286 MarkingState::Internal(this).live_bytes()); |
3289 } | 3287 } |
3290 | 3288 |
3291 #endif // DEBUG | 3289 #endif // DEBUG |
3292 } // namespace internal | 3290 } // namespace internal |
3293 } // namespace v8 | 3291 } // namespace v8 |
OLD | NEW |