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 "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/slot-set.h" | 10 #include "src/heap/slot-set.h" |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 // Failed to commit the body. Release the mapping and any partially | 418 // Failed to commit the body. Release the mapping and any partially |
419 // commited regions inside it. | 419 // commited regions inside it. |
420 reservation.Release(); | 420 reservation.Release(); |
421 return NULL; | 421 return NULL; |
422 } | 422 } |
423 | 423 |
424 controller->TakeControl(&reservation); | 424 controller->TakeControl(&reservation); |
425 return base; | 425 return base; |
426 } | 426 } |
427 | 427 |
428 | 428 void Page::InitializeAsAnchor(Space* space) { |
429 void Page::InitializeAsAnchor(PagedSpace* owner) { | 429 set_owner(space); |
430 set_owner(owner); | |
431 set_prev_page(this); | |
432 set_next_page(this); | |
433 } | |
434 | |
435 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { | |
436 set_owner(semi_space); | |
437 set_next_chunk(this); | 430 set_next_chunk(this); |
438 set_prev_chunk(this); | 431 set_prev_chunk(this); |
439 // Flags marks this invalid page as not being in new-space. | |
440 // All real new-space pages will be in new-space. | |
441 SetFlags(0, ~0); | 432 SetFlags(0, ~0); |
| 433 SetFlag(ANCHOR); |
442 } | 434 } |
443 | 435 |
444 MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, | 436 MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, |
445 Address area_start, Address area_end, | 437 Address area_start, Address area_end, |
446 Executability executable, Space* owner, | 438 Executability executable, Space* owner, |
447 base::VirtualMemory* reservation) { | 439 base::VirtualMemory* reservation) { |
448 MemoryChunk* chunk = FromAddress(base); | 440 MemoryChunk* chunk = FromAddress(base); |
449 | 441 |
450 DCHECK(base == chunk->address()); | 442 DCHECK(base == chunk->address()); |
451 | 443 |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 FreePooled(chunk); | 757 FreePooled(chunk); |
766 } | 758 } |
767 } | 759 } |
768 | 760 |
769 template void MemoryAllocator::Free<MemoryAllocator::kRegular>( | 761 template void MemoryAllocator::Free<MemoryAllocator::kRegular>( |
770 MemoryChunk* chunk); | 762 MemoryChunk* chunk); |
771 | 763 |
772 template void MemoryAllocator::Free<MemoryAllocator::kPooled>( | 764 template void MemoryAllocator::Free<MemoryAllocator::kPooled>( |
773 MemoryChunk* chunk); | 765 MemoryChunk* chunk); |
774 | 766 |
775 template <typename PageType, MemoryAllocator::AllocationMode mode, | 767 template <MemoryAllocator::AllocationMode alloc_mode, typename SpaceType> |
776 typename SpaceType> | 768 Page* MemoryAllocator::AllocatePage(intptr_t size, SpaceType* owner, |
777 PageType* MemoryAllocator::AllocatePage(intptr_t size, SpaceType* owner, | 769 Executability executable) { |
778 Executability executable) { | |
779 MemoryChunk* chunk = nullptr; | 770 MemoryChunk* chunk = nullptr; |
780 if (mode == kPooled) { | 771 if (alloc_mode == kPooled) { |
781 DCHECK_EQ(size, static_cast<intptr_t>(MemoryChunk::kAllocatableMemory)); | 772 DCHECK_EQ(size, static_cast<intptr_t>(MemoryChunk::kAllocatableMemory)); |
782 DCHECK_EQ(executable, NOT_EXECUTABLE); | 773 DCHECK_EQ(executable, NOT_EXECUTABLE); |
783 chunk = AllocatePagePooled(owner); | 774 chunk = AllocatePagePooled(owner); |
784 } | 775 } |
785 if (chunk == nullptr) { | 776 if (chunk == nullptr) { |
786 chunk = AllocateChunk(size, size, executable, owner); | 777 chunk = AllocateChunk(size, size, executable, owner); |
787 } | 778 } |
788 if (chunk == nullptr) return nullptr; | 779 if (chunk == nullptr) return nullptr; |
789 return PageType::Initialize(isolate_->heap(), chunk, executable, owner); | 780 return Page::Initialize(isolate_->heap(), chunk, executable, owner); |
790 } | 781 } |
791 | 782 |
792 template Page* MemoryAllocator::AllocatePage<Page, MemoryAllocator::kRegular, | 783 template Page* |
793 PagedSpace>(intptr_t, PagedSpace*, | 784 MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, PagedSpace>( |
794 Executability); | 785 intptr_t size, PagedSpace* owner, Executability executable); |
| 786 template Page* |
| 787 MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, SemiSpace>( |
| 788 intptr_t size, SemiSpace* owner, Executability executable); |
| 789 template Page* |
| 790 MemoryAllocator::AllocatePage<MemoryAllocator::kPooled, SemiSpace>( |
| 791 intptr_t size, SemiSpace* owner, Executability executable); |
795 | 792 |
796 template LargePage* | 793 LargePage* MemoryAllocator::AllocateLargePage(intptr_t size, |
797 MemoryAllocator::AllocatePage<LargePage, MemoryAllocator::kRegular, Space>( | 794 LargeObjectSpace* owner, |
798 intptr_t, Space*, Executability); | 795 Executability executable) { |
799 | 796 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); |
800 template NewSpacePage* MemoryAllocator::AllocatePage< | 797 if (chunk == nullptr) return nullptr; |
801 NewSpacePage, MemoryAllocator::kPooled, SemiSpace>(intptr_t, SemiSpace*, | 798 return LargePage::Initialize(isolate_->heap(), chunk, executable, owner); |
802 Executability); | 799 } |
803 | 800 |
804 template <typename SpaceType> | 801 template <typename SpaceType> |
805 MemoryChunk* MemoryAllocator::AllocatePagePooled(SpaceType* owner) { | 802 MemoryChunk* MemoryAllocator::AllocatePagePooled(SpaceType* owner) { |
806 if (chunk_pool_.is_empty()) return nullptr; | 803 if (chunk_pool_.is_empty()) return nullptr; |
807 const int size = MemoryChunk::kPageSize; | 804 const int size = MemoryChunk::kPageSize; |
808 MemoryChunk* chunk = chunk_pool_.RemoveLast(); | 805 MemoryChunk* chunk = chunk_pool_.RemoveLast(); |
809 const Address start = reinterpret_cast<Address>(chunk); | 806 const Address start = reinterpret_cast<Address>(chunk); |
810 const Address area_start = start + MemoryChunk::kObjectStartOffset; | 807 const Address area_start = start + MemoryChunk::kObjectStartOffset; |
811 const Address area_end = start + size; | 808 const Address area_end = start + size; |
812 CommitBlock(reinterpret_cast<Address>(chunk), size, NOT_EXECUTABLE); | 809 CommitBlock(reinterpret_cast<Address>(chunk), size, NOT_EXECUTABLE); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 if (!allocation_observers_paused_) { | 1031 if (!allocation_observers_paused_) { |
1035 for (int i = 0; i < allocation_observers_->length(); ++i) { | 1032 for (int i = 0; i < allocation_observers_->length(); ++i) { |
1036 AllocationObserver* o = (*allocation_observers_)[i]; | 1033 AllocationObserver* o = (*allocation_observers_)[i]; |
1037 o->AllocationStep(size, soon_object, size); | 1034 o->AllocationStep(size, soon_object, size); |
1038 } | 1035 } |
1039 } | 1036 } |
1040 } | 1037 } |
1041 | 1038 |
1042 PagedSpace::PagedSpace(Heap* heap, AllocationSpace space, | 1039 PagedSpace::PagedSpace(Heap* heap, AllocationSpace space, |
1043 Executability executable) | 1040 Executability executable) |
1044 : Space(heap, space, executable), free_list_(this) { | 1041 : Space(heap, space, executable), anchor_(this), free_list_(this) { |
1045 area_size_ = MemoryAllocator::PageAreaSize(space); | 1042 area_size_ = MemoryAllocator::PageAreaSize(space); |
1046 accounting_stats_.Clear(); | 1043 accounting_stats_.Clear(); |
1047 | 1044 |
1048 allocation_info_.Reset(nullptr, nullptr); | 1045 allocation_info_.Reset(nullptr, nullptr); |
1049 | |
1050 anchor_.InitializeAsAnchor(this); | |
1051 } | 1046 } |
1052 | 1047 |
1053 | 1048 |
1054 bool PagedSpace::SetUp() { return true; } | 1049 bool PagedSpace::SetUp() { return true; } |
1055 | 1050 |
1056 | 1051 |
1057 bool PagedSpace::HasBeenSetUp() { return true; } | 1052 bool PagedSpace::HasBeenSetUp() { return true; } |
1058 | 1053 |
1059 | 1054 |
1060 void PagedSpace::TearDown() { | 1055 void PagedSpace::TearDown() { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 | 1168 |
1174 | 1169 |
1175 bool PagedSpace::Expand() { | 1170 bool PagedSpace::Expand() { |
1176 int size = AreaSize(); | 1171 int size = AreaSize(); |
1177 if (snapshotable() && !HasPages()) { | 1172 if (snapshotable() && !HasPages()) { |
1178 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); | 1173 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); |
1179 } | 1174 } |
1180 | 1175 |
1181 if (!heap()->CanExpandOldGeneration(size)) return false; | 1176 if (!heap()->CanExpandOldGeneration(size)) return false; |
1182 | 1177 |
1183 Page* p = | 1178 Page* p = heap()->memory_allocator()->AllocatePage(size, this, executable()); |
1184 heap()->memory_allocator()->AllocatePage<Page>(size, this, executable()); | |
1185 if (p == nullptr) return false; | 1179 if (p == nullptr) return false; |
1186 | 1180 |
1187 AccountCommitted(static_cast<intptr_t>(p->size())); | 1181 AccountCommitted(static_cast<intptr_t>(p->size())); |
1188 | 1182 |
1189 // Pages created during bootstrapping may contain immortal immovable objects. | 1183 // Pages created during bootstrapping may contain immortal immovable objects. |
1190 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); | 1184 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); |
1191 | 1185 |
1192 // When incremental marking was activated, old space pages are allocated | 1186 // When incremental marking was activated, old space pages are allocated |
1193 // black. | 1187 // black. |
1194 if (heap()->incremental_marking()->black_allocation() && | 1188 if (heap()->incremental_marking()->black_allocation() && |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 } | 1227 } |
1234 | 1228 |
1235 void PagedSpace::ReleasePage(Page* page) { | 1229 void PagedSpace::ReleasePage(Page* page) { |
1236 DCHECK_EQ(page->LiveBytes(), 0); | 1230 DCHECK_EQ(page->LiveBytes(), 0); |
1237 DCHECK_EQ(AreaSize(), page->area_size()); | 1231 DCHECK_EQ(AreaSize(), page->area_size()); |
1238 DCHECK_EQ(page->owner(), this); | 1232 DCHECK_EQ(page->owner(), this); |
1239 | 1233 |
1240 free_list_.EvictFreeListItems(page); | 1234 free_list_.EvictFreeListItems(page); |
1241 DCHECK(!free_list_.ContainsPageFreeListItems(page)); | 1235 DCHECK(!free_list_.ContainsPageFreeListItems(page)); |
1242 | 1236 |
1243 if (Page::FromAllocationTop(allocation_info_.top()) == page) { | 1237 if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { |
1244 allocation_info_.Reset(nullptr, nullptr); | 1238 allocation_info_.Reset(nullptr, nullptr); |
1245 } | 1239 } |
1246 | 1240 |
1247 // If page is still in a list, unlink it from that list. | 1241 // If page is still in a list, unlink it from that list. |
1248 if (page->next_chunk() != NULL) { | 1242 if (page->next_chunk() != NULL) { |
1249 DCHECK(page->prev_chunk() != NULL); | 1243 DCHECK(page->prev_chunk() != NULL); |
1250 page->Unlink(); | 1244 page->Unlink(); |
1251 } | 1245 } |
1252 | 1246 |
1253 AccountUncommitted(static_cast<intptr_t>(page->size())); | 1247 AccountUncommitted(static_cast<intptr_t>(page->size())); |
1254 heap()->QueueMemoryChunkForFree(page); | 1248 heap()->QueueMemoryChunkForFree(page); |
1255 | 1249 |
1256 DCHECK(Capacity() > 0); | 1250 DCHECK(Capacity() > 0); |
1257 accounting_stats_.ShrinkSpace(AreaSize()); | 1251 accounting_stats_.ShrinkSpace(AreaSize()); |
1258 } | 1252 } |
1259 | 1253 |
1260 #ifdef DEBUG | 1254 #ifdef DEBUG |
1261 void PagedSpace::Print() {} | 1255 void PagedSpace::Print() {} |
1262 #endif | 1256 #endif |
1263 | 1257 |
1264 #ifdef VERIFY_HEAP | 1258 #ifdef VERIFY_HEAP |
1265 void PagedSpace::Verify(ObjectVisitor* visitor) { | 1259 void PagedSpace::Verify(ObjectVisitor* visitor) { |
1266 bool allocation_pointer_found_in_space = | 1260 bool allocation_pointer_found_in_space = |
1267 (allocation_info_.top() == allocation_info_.limit()); | 1261 (allocation_info_.top() == allocation_info_.limit()); |
1268 PageIterator page_iterator(this); | 1262 PageIterator page_iterator(this); |
1269 while (page_iterator.has_next()) { | 1263 while (page_iterator.has_next()) { |
1270 Page* page = page_iterator.next(); | 1264 Page* page = page_iterator.next(); |
1271 CHECK(page->owner() == this); | 1265 CHECK(page->owner() == this); |
1272 if (page == Page::FromAllocationTop(allocation_info_.top())) { | 1266 if (page == Page::FromAllocationAreaAddress(allocation_info_.top())) { |
1273 allocation_pointer_found_in_space = true; | 1267 allocation_pointer_found_in_space = true; |
1274 } | 1268 } |
1275 CHECK(page->SweepingDone()); | 1269 CHECK(page->SweepingDone()); |
1276 HeapObjectIterator it(page); | 1270 HeapObjectIterator it(page); |
1277 Address end_of_previous_object = page->area_start(); | 1271 Address end_of_previous_object = page->area_start(); |
1278 Address top = page->area_end(); | 1272 Address top = page->area_end(); |
1279 int black_size = 0; | 1273 int black_size = 0; |
1280 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 1274 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
1281 CHECK(end_of_previous_object <= object->address()); | 1275 CHECK(end_of_previous_object <= object->address()); |
1282 | 1276 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 Address new_top = allocation_info_.top() + size_in_bytes; | 1475 Address new_top = allocation_info_.top() + size_in_bytes; |
1482 Address new_limit = new_top + GetNextInlineAllocationStepSize() - 1; | 1476 Address new_limit = new_top + GetNextInlineAllocationStepSize() - 1; |
1483 allocation_info_.set_limit(Min(new_limit, high)); | 1477 allocation_info_.set_limit(Min(new_limit, high)); |
1484 } | 1478 } |
1485 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1479 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1486 } | 1480 } |
1487 | 1481 |
1488 | 1482 |
1489 bool NewSpace::AddFreshPage() { | 1483 bool NewSpace::AddFreshPage() { |
1490 Address top = allocation_info_.top(); | 1484 Address top = allocation_info_.top(); |
1491 DCHECK(!NewSpacePage::IsAtStart(top)); | 1485 DCHECK(!Page::IsAtObjectStart(top)); |
1492 if (!to_space_.AdvancePage()) { | 1486 if (!to_space_.AdvancePage()) { |
1493 // No more pages left to advance. | 1487 // No more pages left to advance. |
1494 return false; | 1488 return false; |
1495 } | 1489 } |
1496 | 1490 |
1497 // Clear remainder of current page. | 1491 // Clear remainder of current page. |
1498 Address limit = NewSpacePage::FromLimit(top)->area_end(); | 1492 Address limit = Page::FromAllocationAreaAddress(top)->area_end(); |
1499 if (heap()->gc_state() == Heap::SCAVENGE) { | 1493 if (heap()->gc_state() == Heap::SCAVENGE) { |
1500 heap()->promotion_queue()->SetNewLimit(limit); | 1494 heap()->promotion_queue()->SetNewLimit(limit); |
1501 } | 1495 } |
1502 | 1496 |
1503 int remaining_in_page = static_cast<int>(limit - top); | 1497 int remaining_in_page = static_cast<int>(limit - top); |
1504 heap()->CreateFillerObjectAt(top, remaining_in_page, ClearRecordedSlots::kNo); | 1498 heap()->CreateFillerObjectAt(top, remaining_in_page, ClearRecordedSlots::kNo); |
1505 pages_used_++; | 1499 pages_used_++; |
1506 allocated_since_last_gc_ += NewSpacePage::kAllocatableMemory; | 1500 allocated_since_last_gc_ += Page::kAllocatableMemory; |
1507 UpdateAllocationInfo(); | 1501 UpdateAllocationInfo(); |
1508 | 1502 |
1509 return true; | 1503 return true; |
1510 } | 1504 } |
1511 | 1505 |
1512 | 1506 |
1513 bool NewSpace::AddFreshPageSynchronized() { | 1507 bool NewSpace::AddFreshPageSynchronized() { |
1514 base::LockGuard<base::Mutex> guard(&mutex_); | 1508 base::LockGuard<base::Mutex> guard(&mutex_); |
1515 return AddFreshPage(); | 1509 return AddFreshPage(); |
1516 } | 1510 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1615 void NewSpace::Verify() { | 1609 void NewSpace::Verify() { |
1616 // The allocation pointer should be in the space or at the very end. | 1610 // The allocation pointer should be in the space or at the very end. |
1617 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1611 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1618 | 1612 |
1619 // There should be objects packed in from the low address up to the | 1613 // There should be objects packed in from the low address up to the |
1620 // allocation pointer. | 1614 // allocation pointer. |
1621 Address current = to_space_.first_page()->area_start(); | 1615 Address current = to_space_.first_page()->area_start(); |
1622 CHECK_EQ(current, to_space_.space_start()); | 1616 CHECK_EQ(current, to_space_.space_start()); |
1623 | 1617 |
1624 while (current != top()) { | 1618 while (current != top()) { |
1625 if (!NewSpacePage::IsAtEnd(current)) { | 1619 if (!Page::IsAlignedToPageSize(current)) { |
1626 // The allocation pointer should not be in the middle of an object. | 1620 // The allocation pointer should not be in the middle of an object. |
1627 CHECK(!NewSpacePage::FromLimit(current)->ContainsLimit(top()) || | 1621 CHECK(!Page::FromAllocationAreaAddress(current)->ContainsLimit(top()) || |
1628 current < top()); | 1622 current < top()); |
1629 | 1623 |
1630 HeapObject* object = HeapObject::FromAddress(current); | 1624 HeapObject* object = HeapObject::FromAddress(current); |
1631 | 1625 |
1632 // The first word should be a map, and we expect all map pointers to | 1626 // The first word should be a map, and we expect all map pointers to |
1633 // be in map space. | 1627 // be in map space. |
1634 Map* map = object->map(); | 1628 Map* map = object->map(); |
1635 CHECK(map->IsMap()); | 1629 CHECK(map->IsMap()); |
1636 CHECK(heap()->map_space()->Contains(map)); | 1630 CHECK(heap()->map_space()->Contains(map)); |
1637 | 1631 |
1638 // The object should not be code or a map. | 1632 // The object should not be code or a map. |
1639 CHECK(!object->IsMap()); | 1633 CHECK(!object->IsMap()); |
1640 CHECK(!object->IsAbstractCode()); | 1634 CHECK(!object->IsAbstractCode()); |
1641 | 1635 |
1642 // The object itself should look OK. | 1636 // The object itself should look OK. |
1643 object->ObjectVerify(); | 1637 object->ObjectVerify(); |
1644 | 1638 |
1645 // All the interior pointers should be contained in the heap. | 1639 // All the interior pointers should be contained in the heap. |
1646 VerifyPointersVisitor visitor; | 1640 VerifyPointersVisitor visitor; |
1647 int size = object->Size(); | 1641 int size = object->Size(); |
1648 object->IterateBody(map->instance_type(), size, &visitor); | 1642 object->IterateBody(map->instance_type(), size, &visitor); |
1649 | 1643 |
1650 current += size; | 1644 current += size; |
1651 } else { | 1645 } else { |
1652 // At end of page, switch to next page. | 1646 // At end of page, switch to next page. |
1653 NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page(); | 1647 Page* page = Page::FromAllocationAreaAddress(current)->next_page(); |
1654 // Next page should be valid. | 1648 // Next page should be valid. |
1655 CHECK(!page->is_anchor()); | 1649 CHECK(!page->is_anchor()); |
1656 current = page->area_start(); | 1650 current = page->area_start(); |
1657 } | 1651 } |
1658 } | 1652 } |
1659 | 1653 |
1660 // Check semi-spaces. | 1654 // Check semi-spaces. |
1661 CHECK_EQ(from_space_.id(), kFromSpace); | 1655 CHECK_EQ(from_space_.id(), kFromSpace); |
1662 CHECK_EQ(to_space_.id(), kToSpace); | 1656 CHECK_EQ(to_space_.id(), kToSpace); |
1663 from_space_.Verify(); | 1657 from_space_.Verify(); |
(...skipping 15 matching lines...) Expand all Loading... |
1679 | 1673 |
1680 void SemiSpace::TearDown() { | 1674 void SemiSpace::TearDown() { |
1681 // Properly uncommit memory to keep the allocator counters in sync. | 1675 // Properly uncommit memory to keep the allocator counters in sync. |
1682 if (is_committed()) Uncommit(); | 1676 if (is_committed()) Uncommit(); |
1683 current_capacity_ = maximum_capacity_ = 0; | 1677 current_capacity_ = maximum_capacity_ = 0; |
1684 } | 1678 } |
1685 | 1679 |
1686 | 1680 |
1687 bool SemiSpace::Commit() { | 1681 bool SemiSpace::Commit() { |
1688 DCHECK(!is_committed()); | 1682 DCHECK(!is_committed()); |
1689 NewSpacePage* current = anchor(); | 1683 Page* current = anchor(); |
1690 const int num_pages = current_capacity_ / Page::kPageSize; | 1684 const int num_pages = current_capacity_ / Page::kPageSize; |
1691 for (int pages_added = 0; pages_added < num_pages; pages_added++) { | 1685 for (int pages_added = 0; pages_added < num_pages; pages_added++) { |
1692 NewSpacePage* new_page = | 1686 Page* new_page = |
1693 heap() | 1687 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
1694 ->memory_allocator() | 1688 Page::kAllocatableMemory, this, executable()); |
1695 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( | |
1696 NewSpacePage::kAllocatableMemory, this, executable()); | |
1697 if (new_page == nullptr) { | 1689 if (new_page == nullptr) { |
1698 RewindPages(current, pages_added); | 1690 RewindPages(current, pages_added); |
1699 return false; | 1691 return false; |
1700 } | 1692 } |
1701 new_page->InsertAfter(current); | 1693 new_page->InsertAfter(current); |
1702 current = new_page; | 1694 current = new_page; |
1703 } | 1695 } |
1704 Reset(); | 1696 Reset(); |
1705 AccountCommitted(current_capacity_); | 1697 AccountCommitted(current_capacity_); |
1706 if (age_mark_ == nullptr) { | 1698 if (age_mark_ == nullptr) { |
(...skipping 26 matching lines...) Expand all Loading... |
1733 size += it.next()->CommittedPhysicalMemory(); | 1725 size += it.next()->CommittedPhysicalMemory(); |
1734 } | 1726 } |
1735 return size; | 1727 return size; |
1736 } | 1728 } |
1737 | 1729 |
1738 | 1730 |
1739 bool SemiSpace::GrowTo(int new_capacity) { | 1731 bool SemiSpace::GrowTo(int new_capacity) { |
1740 if (!is_committed()) { | 1732 if (!is_committed()) { |
1741 if (!Commit()) return false; | 1733 if (!Commit()) return false; |
1742 } | 1734 } |
1743 DCHECK_EQ(new_capacity & NewSpacePage::kPageAlignmentMask, 0); | 1735 DCHECK_EQ(new_capacity & Page::kPageAlignmentMask, 0); |
1744 DCHECK_LE(new_capacity, maximum_capacity_); | 1736 DCHECK_LE(new_capacity, maximum_capacity_); |
1745 DCHECK_GT(new_capacity, current_capacity_); | 1737 DCHECK_GT(new_capacity, current_capacity_); |
1746 const int delta = new_capacity - current_capacity_; | 1738 const int delta = new_capacity - current_capacity_; |
1747 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); | 1739 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); |
1748 const int delta_pages = delta / NewSpacePage::kPageSize; | 1740 const int delta_pages = delta / Page::kPageSize; |
1749 NewSpacePage* last_page = anchor()->prev_page(); | 1741 Page* last_page = anchor()->prev_page(); |
1750 DCHECK_NE(last_page, anchor()); | 1742 DCHECK_NE(last_page, anchor()); |
1751 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { | 1743 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { |
1752 NewSpacePage* new_page = | 1744 Page* new_page = |
1753 heap() | 1745 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
1754 ->memory_allocator() | 1746 Page::kAllocatableMemory, this, executable()); |
1755 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( | |
1756 NewSpacePage::kAllocatableMemory, this, executable()); | |
1757 if (new_page == nullptr) { | 1747 if (new_page == nullptr) { |
1758 RewindPages(last_page, pages_added); | 1748 RewindPages(last_page, pages_added); |
1759 return false; | 1749 return false; |
1760 } | 1750 } |
1761 new_page->InsertAfter(last_page); | 1751 new_page->InsertAfter(last_page); |
1762 Bitmap::Clear(new_page); | 1752 Bitmap::Clear(new_page); |
1763 // Duplicate the flags that was set on the old page. | 1753 // Duplicate the flags that was set on the old page. |
1764 new_page->SetFlags(last_page->GetFlags(), | 1754 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); |
1765 NewSpacePage::kCopyOnFlipFlagsMask); | |
1766 last_page = new_page; | 1755 last_page = new_page; |
1767 } | 1756 } |
1768 AccountCommitted(static_cast<intptr_t>(delta)); | 1757 AccountCommitted(static_cast<intptr_t>(delta)); |
1769 current_capacity_ = new_capacity; | 1758 current_capacity_ = new_capacity; |
1770 return true; | 1759 return true; |
1771 } | 1760 } |
1772 | 1761 |
1773 void SemiSpace::RewindPages(NewSpacePage* start, int num_pages) { | 1762 void SemiSpace::RewindPages(Page* start, int num_pages) { |
1774 NewSpacePage* new_last_page = nullptr; | 1763 Page* new_last_page = nullptr; |
1775 NewSpacePage* last_page = start; | 1764 Page* last_page = start; |
1776 while (num_pages > 0) { | 1765 while (num_pages > 0) { |
1777 DCHECK_NE(last_page, anchor()); | 1766 DCHECK_NE(last_page, anchor()); |
1778 new_last_page = last_page->prev_page(); | 1767 new_last_page = last_page->prev_page(); |
1779 last_page->prev_page()->set_next_page(last_page->next_page()); | 1768 last_page->prev_page()->set_next_page(last_page->next_page()); |
1780 last_page->next_page()->set_prev_page(last_page->prev_page()); | 1769 last_page->next_page()->set_prev_page(last_page->prev_page()); |
1781 last_page = new_last_page; | 1770 last_page = new_last_page; |
1782 num_pages--; | 1771 num_pages--; |
1783 } | 1772 } |
1784 } | 1773 } |
1785 | 1774 |
1786 bool SemiSpace::ShrinkTo(int new_capacity) { | 1775 bool SemiSpace::ShrinkTo(int new_capacity) { |
1787 DCHECK_EQ(new_capacity & NewSpacePage::kPageAlignmentMask, 0); | 1776 DCHECK_EQ(new_capacity & Page::kPageAlignmentMask, 0); |
1788 DCHECK_GE(new_capacity, minimum_capacity_); | 1777 DCHECK_GE(new_capacity, minimum_capacity_); |
1789 DCHECK_LT(new_capacity, current_capacity_); | 1778 DCHECK_LT(new_capacity, current_capacity_); |
1790 if (is_committed()) { | 1779 if (is_committed()) { |
1791 const int delta = current_capacity_ - new_capacity; | 1780 const int delta = current_capacity_ - new_capacity; |
1792 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); | 1781 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); |
1793 int delta_pages = delta / NewSpacePage::kPageSize; | 1782 int delta_pages = delta / Page::kPageSize; |
1794 NewSpacePage* new_last_page; | 1783 Page* new_last_page; |
1795 NewSpacePage* last_page; | 1784 Page* last_page; |
1796 while (delta_pages > 0) { | 1785 while (delta_pages > 0) { |
1797 last_page = anchor()->prev_page(); | 1786 last_page = anchor()->prev_page(); |
1798 new_last_page = last_page->prev_page(); | 1787 new_last_page = last_page->prev_page(); |
1799 new_last_page->set_next_page(anchor()); | 1788 new_last_page->set_next_page(anchor()); |
1800 anchor()->set_prev_page(new_last_page); | 1789 anchor()->set_prev_page(new_last_page); |
1801 heap()->memory_allocator()->Free<MemoryAllocator::kPooled>(last_page); | 1790 heap()->memory_allocator()->Free<MemoryAllocator::kPooled>(last_page); |
1802 delta_pages--; | 1791 delta_pages--; |
1803 } | 1792 } |
1804 AccountUncommitted(static_cast<intptr_t>(delta)); | 1793 AccountUncommitted(static_cast<intptr_t>(delta)); |
1805 } | 1794 } |
1806 current_capacity_ = new_capacity; | 1795 current_capacity_ = new_capacity; |
1807 return true; | 1796 return true; |
1808 } | 1797 } |
1809 | 1798 |
1810 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { | 1799 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { |
1811 anchor_.set_owner(this); | 1800 anchor_.set_owner(this); |
1812 // Fixup back-pointers to anchor. Address of anchor changes when we swap. | |
1813 anchor_.prev_page()->set_next_page(&anchor_); | 1801 anchor_.prev_page()->set_next_page(&anchor_); |
1814 anchor_.next_page()->set_prev_page(&anchor_); | 1802 anchor_.next_page()->set_prev_page(&anchor_); |
1815 | 1803 |
1816 NewSpacePageIterator it(this); | 1804 NewSpacePageIterator it(this); |
1817 while (it.has_next()) { | 1805 while (it.has_next()) { |
1818 NewSpacePage* page = it.next(); | 1806 Page* page = it.next(); |
1819 page->set_owner(this); | 1807 page->set_owner(this); |
1820 page->SetFlags(flags, mask); | 1808 page->SetFlags(flags, mask); |
1821 if (id_ == kToSpace) { | 1809 if (id_ == kToSpace) { |
1822 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 1810 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
1823 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 1811 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
1824 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 1812 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
1825 page->ResetLiveBytes(); | 1813 page->ResetLiveBytes(); |
1826 } else { | 1814 } else { |
1827 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 1815 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
1828 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 1816 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
1829 } | 1817 } |
1830 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 1818 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
1831 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 1819 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
1832 } | 1820 } |
1833 } | 1821 } |
1834 | 1822 |
1835 | 1823 |
1836 void SemiSpace::Reset() { | 1824 void SemiSpace::Reset() { |
1837 DCHECK_NE(anchor_.next_page(), &anchor_); | 1825 DCHECK_NE(anchor_.next_page(), &anchor_); |
1838 current_page_ = anchor_.next_page(); | 1826 current_page_ = anchor_.next_page(); |
1839 } | 1827 } |
1840 | 1828 |
1841 void SemiSpace::ReplaceWithEmptyPage(NewSpacePage* old_page) { | 1829 void SemiSpace::ReplaceWithEmptyPage(Page* old_page) { |
1842 NewSpacePage* new_page = | 1830 Page* new_page = heap()->memory_allocator()->AllocatePage( |
1843 heap()->memory_allocator()->AllocatePage<NewSpacePage>( | 1831 Page::kAllocatableMemory, this, executable()); |
1844 NewSpacePage::kAllocatableMemory, this, executable()); | |
1845 Bitmap::Clear(new_page); | 1832 Bitmap::Clear(new_page); |
1846 new_page->SetFlags(old_page->GetFlags(), NewSpacePage::kCopyAllFlags); | 1833 new_page->SetFlags(old_page->GetFlags(), Page::kCopyAllFlags); |
1847 new_page->set_next_page(old_page->next_page()); | 1834 new_page->set_next_page(old_page->next_page()); |
1848 new_page->set_prev_page(old_page->prev_page()); | 1835 new_page->set_prev_page(old_page->prev_page()); |
1849 old_page->next_page()->set_prev_page(new_page); | 1836 old_page->next_page()->set_prev_page(new_page); |
1850 old_page->prev_page()->set_next_page(new_page); | 1837 old_page->prev_page()->set_next_page(new_page); |
1851 heap()->CreateFillerObjectAt(new_page->area_start(), new_page->area_size(), | 1838 heap()->CreateFillerObjectAt(new_page->area_start(), new_page->area_size(), |
1852 ClearRecordedSlots::kNo); | 1839 ClearRecordedSlots::kNo); |
1853 } | 1840 } |
1854 | 1841 |
1855 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { | 1842 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { |
1856 // We won't be swapping semispaces without data in them. | 1843 // We won't be swapping semispaces without data in them. |
1857 DCHECK_NE(from->anchor_.next_page(), &from->anchor_); | 1844 DCHECK_NE(from->anchor_.next_page(), &from->anchor_); |
1858 DCHECK_NE(to->anchor_.next_page(), &to->anchor_); | 1845 DCHECK_NE(to->anchor_.next_page(), &to->anchor_); |
1859 | 1846 |
1860 intptr_t saved_to_space_flags = to->current_page()->GetFlags(); | 1847 intptr_t saved_to_space_flags = to->current_page()->GetFlags(); |
1861 | 1848 |
1862 // We swap all properties but id_. | 1849 // We swap all properties but id_. |
1863 std::swap(from->current_capacity_, to->current_capacity_); | 1850 std::swap(from->current_capacity_, to->current_capacity_); |
1864 std::swap(from->maximum_capacity_, to->maximum_capacity_); | 1851 std::swap(from->maximum_capacity_, to->maximum_capacity_); |
1865 std::swap(from->minimum_capacity_, to->minimum_capacity_); | 1852 std::swap(from->minimum_capacity_, to->minimum_capacity_); |
1866 std::swap(from->age_mark_, to->age_mark_); | 1853 std::swap(from->age_mark_, to->age_mark_); |
1867 std::swap(from->committed_, to->committed_); | 1854 std::swap(from->committed_, to->committed_); |
1868 std::swap(from->anchor_, to->anchor_); | 1855 std::swap(from->anchor_, to->anchor_); |
1869 std::swap(from->current_page_, to->current_page_); | 1856 std::swap(from->current_page_, to->current_page_); |
1870 | 1857 |
1871 to->FixPagesFlags(saved_to_space_flags, NewSpacePage::kCopyOnFlipFlagsMask); | 1858 to->FixPagesFlags(saved_to_space_flags, Page::kCopyOnFlipFlagsMask); |
1872 from->FixPagesFlags(0, 0); | 1859 from->FixPagesFlags(0, 0); |
1873 } | 1860 } |
1874 | 1861 |
1875 | 1862 |
1876 void SemiSpace::set_age_mark(Address mark) { | 1863 void SemiSpace::set_age_mark(Address mark) { |
1877 DCHECK_EQ(NewSpacePage::FromLimit(mark)->semi_space(), this); | 1864 DCHECK_EQ(Page::FromAllocationAreaAddress(mark)->owner(), this); |
1878 age_mark_ = mark; | 1865 age_mark_ = mark; |
1879 // Mark all pages up to the one containing mark. | 1866 // Mark all pages up to the one containing mark. |
1880 NewSpacePageIterator it(space_start(), mark); | 1867 NewSpacePageIterator it(space_start(), mark); |
1881 while (it.has_next()) { | 1868 while (it.has_next()) { |
1882 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 1869 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
1883 } | 1870 } |
1884 } | 1871 } |
1885 | 1872 |
1886 | 1873 |
1887 #ifdef DEBUG | 1874 #ifdef DEBUG |
1888 void SemiSpace::Print() {} | 1875 void SemiSpace::Print() {} |
1889 #endif | 1876 #endif |
1890 | 1877 |
1891 #ifdef VERIFY_HEAP | 1878 #ifdef VERIFY_HEAP |
1892 void SemiSpace::Verify() { | 1879 void SemiSpace::Verify() { |
1893 bool is_from_space = (id_ == kFromSpace); | 1880 bool is_from_space = (id_ == kFromSpace); |
1894 NewSpacePage* page = anchor_.next_page(); | 1881 Page* page = anchor_.next_page(); |
1895 CHECK(anchor_.semi_space() == this); | 1882 CHECK(anchor_.owner() == this); |
1896 while (page != &anchor_) { | 1883 while (page != &anchor_) { |
1897 CHECK_EQ(page->semi_space(), this); | 1884 CHECK_EQ(page->owner(), this); |
1898 CHECK(page->InNewSpace()); | 1885 CHECK(page->InNewSpace()); |
1899 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE | 1886 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE |
1900 : MemoryChunk::IN_TO_SPACE)); | 1887 : MemoryChunk::IN_TO_SPACE)); |
1901 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE | 1888 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE |
1902 : MemoryChunk::IN_FROM_SPACE)); | 1889 : MemoryChunk::IN_FROM_SPACE)); |
1903 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); | 1890 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); |
1904 if (!is_from_space) { | 1891 if (!is_from_space) { |
1905 // The pointers-from-here-are-interesting flag isn't updated dynamically | 1892 // The pointers-from-here-are-interesting flag isn't updated dynamically |
1906 // on from-space pages, so it might be out of sync with the marking state. | 1893 // on from-space pages, so it might be out of sync with the marking state. |
1907 if (page->heap()->incremental_marking()->IsMarking()) { | 1894 if (page->heap()->incremental_marking()->IsMarking()) { |
1908 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1895 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
1909 } else { | 1896 } else { |
1910 CHECK( | 1897 CHECK( |
1911 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1898 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
1912 } | 1899 } |
1913 // TODO(gc): Check that the live_bytes_count_ field matches the | 1900 // TODO(gc): Check that the live_bytes_count_ field matches the |
1914 // black marking on the page (if we make it match in new-space). | 1901 // black marking on the page (if we make it match in new-space). |
1915 } | 1902 } |
1916 CHECK_EQ(page->prev_page()->next_page(), page); | 1903 CHECK_EQ(page->prev_page()->next_page(), page); |
1917 page = page->next_page(); | 1904 page = page->next_page(); |
1918 } | 1905 } |
1919 } | 1906 } |
1920 #endif | 1907 #endif |
1921 | 1908 |
1922 #ifdef DEBUG | 1909 #ifdef DEBUG |
1923 void SemiSpace::AssertValidRange(Address start, Address end) { | 1910 void SemiSpace::AssertValidRange(Address start, Address end) { |
1924 // Addresses belong to same semi-space | 1911 // Addresses belong to same semi-space |
1925 NewSpacePage* page = NewSpacePage::FromLimit(start); | 1912 Page* page = Page::FromAllocationAreaAddress(start); |
1926 NewSpacePage* end_page = NewSpacePage::FromLimit(end); | 1913 Page* end_page = Page::FromAllocationAreaAddress(end); |
1927 SemiSpace* space = page->semi_space(); | 1914 SemiSpace* space = reinterpret_cast<SemiSpace*>(page->owner()); |
1928 CHECK_EQ(space, end_page->semi_space()); | 1915 CHECK_EQ(space, end_page->owner()); |
1929 // Start address is before end address, either on same page, | 1916 // Start address is before end address, either on same page, |
1930 // or end address is on a later page in the linked list of | 1917 // or end address is on a later page in the linked list of |
1931 // semi-space pages. | 1918 // semi-space pages. |
1932 if (page == end_page) { | 1919 if (page == end_page) { |
1933 CHECK_LE(start, end); | 1920 CHECK_LE(start, end); |
1934 } else { | 1921 } else { |
1935 while (page != end_page) { | 1922 while (page != end_page) { |
1936 page = page->next_page(); | 1923 page = page->next_page(); |
1937 CHECK_NE(page, space->anchor()); | 1924 CHECK_NE(page, space->anchor()); |
1938 } | 1925 } |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2592 if (size == 0) continue; | 2579 if (size == 0) continue; |
2593 Address address = page->OffsetToAddress(Page::kPageSize - size); | 2580 Address address = page->OffsetToAddress(Page::kPageSize - size); |
2594 heap()->CreateFillerObjectAt(address, size, ClearRecordedSlots::kNo); | 2581 heap()->CreateFillerObjectAt(address, size, ClearRecordedSlots::kNo); |
2595 } | 2582 } |
2596 } | 2583 } |
2597 | 2584 |
2598 | 2585 |
2599 void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() { | 2586 void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() { |
2600 if (allocation_info_.top() >= allocation_info_.limit()) return; | 2587 if (allocation_info_.top() >= allocation_info_.limit()) return; |
2601 | 2588 |
2602 if (!Page::FromAllocationTop(allocation_info_.top())->CanAllocate()) { | 2589 if (!Page::FromAllocationAreaAddress(allocation_info_.top())->CanAllocate()) { |
2603 // Create filler object to keep page iterable if it was iterable. | 2590 // Create filler object to keep page iterable if it was iterable. |
2604 int remaining = | 2591 int remaining = |
2605 static_cast<int>(allocation_info_.limit() - allocation_info_.top()); | 2592 static_cast<int>(allocation_info_.limit() - allocation_info_.top()); |
2606 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining, | 2593 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining, |
2607 ClearRecordedSlots::kNo); | 2594 ClearRecordedSlots::kNo); |
2608 allocation_info_.Reset(nullptr, nullptr); | 2595 allocation_info_.Reset(nullptr, nullptr); |
2609 } | 2596 } |
2610 } | 2597 } |
2611 | 2598 |
2612 | 2599 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2901 | 2888 |
2902 | 2889 |
2903 AllocationResult LargeObjectSpace::AllocateRaw(int object_size, | 2890 AllocationResult LargeObjectSpace::AllocateRaw(int object_size, |
2904 Executability executable) { | 2891 Executability executable) { |
2905 // Check if we want to force a GC before growing the old space further. | 2892 // Check if we want to force a GC before growing the old space further. |
2906 // If so, fail the allocation. | 2893 // If so, fail the allocation. |
2907 if (!heap()->CanExpandOldGeneration(object_size)) { | 2894 if (!heap()->CanExpandOldGeneration(object_size)) { |
2908 return AllocationResult::Retry(identity()); | 2895 return AllocationResult::Retry(identity()); |
2909 } | 2896 } |
2910 | 2897 |
2911 LargePage* page = heap()->memory_allocator()->AllocatePage<LargePage>( | 2898 LargePage* page = heap()->memory_allocator()->AllocateLargePage( |
2912 object_size, this, executable); | 2899 object_size, this, executable); |
2913 if (page == NULL) return AllocationResult::Retry(identity()); | 2900 if (page == NULL) return AllocationResult::Retry(identity()); |
2914 DCHECK(page->area_size() >= object_size); | 2901 DCHECK(page->area_size() >= object_size); |
2915 | 2902 |
2916 size_ += static_cast<int>(page->size()); | 2903 size_ += static_cast<int>(page->size()); |
2917 AccountCommitted(static_cast<intptr_t>(page->size())); | 2904 AccountCommitted(static_cast<intptr_t>(page->size())); |
2918 objects_size_ += object_size; | 2905 objects_size_ += object_size; |
2919 page_count_++; | 2906 page_count_++; |
2920 page->set_next_page(first_page_); | 2907 page->set_next_page(first_page_); |
2921 first_page_ = page; | 2908 first_page_ = page; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2970 } | 2957 } |
2971 | 2958 |
2972 | 2959 |
2973 LargePage* LargeObjectSpace::FindPage(Address a) { | 2960 LargePage* LargeObjectSpace::FindPage(Address a) { |
2974 uintptr_t key = reinterpret_cast<uintptr_t>(a) / MemoryChunk::kAlignment; | 2961 uintptr_t key = reinterpret_cast<uintptr_t>(a) / MemoryChunk::kAlignment; |
2975 HashMap::Entry* e = chunk_map_.Lookup(reinterpret_cast<void*>(key), | 2962 HashMap::Entry* e = chunk_map_.Lookup(reinterpret_cast<void*>(key), |
2976 static_cast<uint32_t>(key)); | 2963 static_cast<uint32_t>(key)); |
2977 if (e != NULL) { | 2964 if (e != NULL) { |
2978 DCHECK(e->value != NULL); | 2965 DCHECK(e->value != NULL); |
2979 LargePage* page = reinterpret_cast<LargePage*>(e->value); | 2966 LargePage* page = reinterpret_cast<LargePage*>(e->value); |
2980 DCHECK(page->is_valid()); | 2967 DCHECK(LargePage::IsValid(page)); |
2981 if (page->Contains(a)) { | 2968 if (page->Contains(a)) { |
2982 return page; | 2969 return page; |
2983 } | 2970 } |
2984 } | 2971 } |
2985 return NULL; | 2972 return NULL; |
2986 } | 2973 } |
2987 | 2974 |
2988 | 2975 |
2989 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { | 2976 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { |
2990 LargePage* current = first_page_; | 2977 LargePage* current = first_page_; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3161 object->ShortPrint(); | 3148 object->ShortPrint(); |
3162 PrintF("\n"); | 3149 PrintF("\n"); |
3163 } | 3150 } |
3164 printf(" --------------------------------------\n"); | 3151 printf(" --------------------------------------\n"); |
3165 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3152 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3166 } | 3153 } |
3167 | 3154 |
3168 #endif // DEBUG | 3155 #endif // DEBUG |
3169 } // namespace internal | 3156 } // namespace internal |
3170 } // namespace v8 | 3157 } // namespace v8 |
OLD | NEW |