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/slots-buffer.h" | 11 #include "src/heap/slots-buffer.h" |
11 #include "src/macro-assembler.h" | 12 #include "src/macro-assembler.h" |
12 #include "src/msan.h" | 13 #include "src/msan.h" |
13 #include "src/snapshot/snapshot.h" | 14 #include "src/snapshot/snapshot.h" |
14 | 15 |
15 namespace v8 { | 16 namespace v8 { |
16 namespace internal { | 17 namespace internal { |
17 | 18 |
18 | 19 |
19 // ---------------------------------------------------------------------------- | 20 // ---------------------------------------------------------------------------- |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 | 422 |
422 | 423 |
423 NewSpacePage* NewSpacePage::Initialize(Heap* heap, Address start, | 424 NewSpacePage* NewSpacePage::Initialize(Heap* heap, Address start, |
424 SemiSpace* semi_space) { | 425 SemiSpace* semi_space) { |
425 Address area_start = start + NewSpacePage::kObjectStartOffset; | 426 Address area_start = start + NewSpacePage::kObjectStartOffset; |
426 Address area_end = start + Page::kPageSize; | 427 Address area_end = start + Page::kPageSize; |
427 | 428 |
428 MemoryChunk* chunk = | 429 MemoryChunk* chunk = |
429 MemoryChunk::Initialize(heap, start, Page::kPageSize, area_start, | 430 MemoryChunk::Initialize(heap, start, Page::kPageSize, area_start, |
430 area_end, NOT_EXECUTABLE, semi_space); | 431 area_end, NOT_EXECUTABLE, semi_space); |
431 chunk->initialize_scan_on_scavenge(true); | |
432 bool in_to_space = (semi_space->id() != kFromSpace); | 432 bool in_to_space = (semi_space->id() != kFromSpace); |
433 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE | 433 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE |
434 : MemoryChunk::IN_FROM_SPACE); | 434 : MemoryChunk::IN_FROM_SPACE); |
435 DCHECK(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE | 435 DCHECK(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE |
436 : MemoryChunk::IN_TO_SPACE)); | 436 : MemoryChunk::IN_TO_SPACE)); |
437 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); | 437 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); |
438 heap->incremental_marking()->SetNewSpacePageFlags(page); | 438 heap->incremental_marking()->SetNewSpacePageFlags(page); |
439 return page; | 439 return page; |
440 } | 440 } |
441 | 441 |
(...skipping 15 matching lines...) Expand all Loading... |
457 | 457 |
458 DCHECK(base == chunk->address()); | 458 DCHECK(base == chunk->address()); |
459 | 459 |
460 chunk->heap_ = heap; | 460 chunk->heap_ = heap; |
461 chunk->size_ = size; | 461 chunk->size_ = size; |
462 chunk->area_start_ = area_start; | 462 chunk->area_start_ = area_start; |
463 chunk->area_end_ = area_end; | 463 chunk->area_end_ = area_end; |
464 chunk->flags_ = 0; | 464 chunk->flags_ = 0; |
465 chunk->set_owner(owner); | 465 chunk->set_owner(owner); |
466 chunk->InitializeReservedMemory(); | 466 chunk->InitializeReservedMemory(); |
467 chunk->slots_buffer_ = NULL; | 467 chunk->slots_buffer_ = nullptr; |
468 chunk->skip_list_ = NULL; | 468 chunk->old_to_new_slots_ = nullptr; |
| 469 chunk->skip_list_ = nullptr; |
469 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity; | 470 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity; |
470 chunk->progress_bar_ = 0; | 471 chunk->progress_bar_ = 0; |
471 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); | 472 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); |
472 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); | 473 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); |
473 chunk->parallel_compaction_state().SetValue(kCompactingDone); | 474 chunk->parallel_compaction_state().SetValue(kCompactingDone); |
474 chunk->mutex_ = NULL; | 475 chunk->mutex_ = nullptr; |
475 chunk->available_in_small_free_list_ = 0; | 476 chunk->available_in_small_free_list_ = 0; |
476 chunk->available_in_medium_free_list_ = 0; | 477 chunk->available_in_medium_free_list_ = 0; |
477 chunk->available_in_large_free_list_ = 0; | 478 chunk->available_in_large_free_list_ = 0; |
478 chunk->available_in_huge_free_list_ = 0; | 479 chunk->available_in_huge_free_list_ = 0; |
479 chunk->non_available_small_blocks_ = 0; | 480 chunk->non_available_small_blocks_ = 0; |
480 chunk->ResetLiveBytes(); | 481 chunk->ResetLiveBytes(); |
481 Bitmap::Clear(chunk); | 482 Bitmap::Clear(chunk); |
482 chunk->initialize_scan_on_scavenge(false); | |
483 chunk->set_next_chunk(nullptr); | 483 chunk->set_next_chunk(nullptr); |
484 chunk->set_prev_chunk(nullptr); | 484 chunk->set_prev_chunk(nullptr); |
485 | 485 |
486 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 486 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
487 DCHECK(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); | 487 DCHECK(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); |
488 | 488 |
489 if (executable == EXECUTABLE) { | 489 if (executable == EXECUTABLE) { |
490 chunk->SetFlag(IS_EXECUTABLE); | 490 chunk->SetFlag(IS_EXECUTABLE); |
491 } | 491 } |
492 | 492 |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 static_cast<PagedSpace*>(chunk->owner())->Allocate(by); | 926 static_cast<PagedSpace*>(chunk->owner())->Allocate(by); |
927 } | 927 } |
928 chunk->IncrementLiveBytes(by); | 928 chunk->IncrementLiveBytes(by); |
929 } | 929 } |
930 | 930 |
931 | 931 |
932 void MemoryChunk::ReleaseAllocatedMemory() { | 932 void MemoryChunk::ReleaseAllocatedMemory() { |
933 delete slots_buffer_; | 933 delete slots_buffer_; |
934 delete skip_list_; | 934 delete skip_list_; |
935 delete mutex_; | 935 delete mutex_; |
| 936 ReleaseOldToNewSlots(); |
| 937 } |
| 938 |
| 939 void MemoryChunk::AllocateOldToNewSlots() { |
| 940 size_t pages = (size_ + Page::kPageSize - 1) / Page::kPageSize; |
| 941 DCHECK(owner() == heap_->lo_space() || pages == 1); |
| 942 DCHECK(pages > 0); |
| 943 DCHECK(nullptr == old_to_new_slots_); |
| 944 old_to_new_slots_ = new SlotSet[pages]; |
| 945 for (size_t i = 0; i < pages; i++) { |
| 946 old_to_new_slots_[i].SetPageStart(address() + i * Page::kPageSize); |
| 947 } |
| 948 } |
| 949 |
| 950 void MemoryChunk::ReleaseOldToNewSlots() { |
| 951 delete[] old_to_new_slots_; |
| 952 old_to_new_slots_ = nullptr; |
936 } | 953 } |
937 | 954 |
938 | 955 |
939 // ----------------------------------------------------------------------------- | 956 // ----------------------------------------------------------------------------- |
940 // PagedSpace implementation | 957 // PagedSpace implementation |
941 | 958 |
942 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == | 959 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == |
943 ObjectSpace::kObjectSpaceNewSpace); | 960 ObjectSpace::kObjectSpaceNewSpace); |
944 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == | 961 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == |
945 ObjectSpace::kObjectSpaceOldSpace); | 962 ObjectSpace::kObjectSpaceOldSpace); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 void PagedSpace::ReleasePage(Page* page, bool evict_free_list_items) { | 1197 void PagedSpace::ReleasePage(Page* page, bool evict_free_list_items) { |
1181 DCHECK(page->LiveBytes() == 0); | 1198 DCHECK(page->LiveBytes() == 0); |
1182 DCHECK(AreaSize() == page->area_size()); | 1199 DCHECK(AreaSize() == page->area_size()); |
1183 | 1200 |
1184 if (evict_free_list_items) { | 1201 if (evict_free_list_items) { |
1185 intptr_t size = free_list_.EvictFreeListItems(page); | 1202 intptr_t size = free_list_.EvictFreeListItems(page); |
1186 accounting_stats_.AllocateBytes(size); | 1203 accounting_stats_.AllocateBytes(size); |
1187 DCHECK_EQ(AreaSize(), static_cast<int>(size)); | 1204 DCHECK_EQ(AreaSize(), static_cast<int>(size)); |
1188 } | 1205 } |
1189 | 1206 |
1190 if (page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)) { | |
1191 heap()->decrement_scan_on_scavenge_pages(); | |
1192 page->ClearFlag(MemoryChunk::SCAN_ON_SCAVENGE); | |
1193 } | |
1194 | |
1195 DCHECK(!free_list_.ContainsPageFreeListItems(page)); | 1207 DCHECK(!free_list_.ContainsPageFreeListItems(page)); |
1196 | 1208 |
1197 if (Page::FromAllocationTop(allocation_info_.top()) == page) { | 1209 if (Page::FromAllocationTop(allocation_info_.top()) == page) { |
1198 allocation_info_.Reset(nullptr, nullptr); | 1210 allocation_info_.Reset(nullptr, nullptr); |
1199 } | 1211 } |
1200 | 1212 |
1201 // If page is still in a list, unlink it from that list. | 1213 // If page is still in a list, unlink it from that list. |
1202 if (page->next_chunk() != NULL) { | 1214 if (page->next_chunk() != NULL) { |
1203 DCHECK(page->prev_chunk() != NULL); | 1215 DCHECK(page->prev_chunk() != NULL); |
1204 page->Unlink(); | 1216 page->Unlink(); |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1819 page->SetFlags(flags, mask); | 1831 page->SetFlags(flags, mask); |
1820 if (becomes_to_space) { | 1832 if (becomes_to_space) { |
1821 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 1833 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
1822 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 1834 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
1823 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 1835 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
1824 page->ResetLiveBytes(); | 1836 page->ResetLiveBytes(); |
1825 } else { | 1837 } else { |
1826 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 1838 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
1827 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 1839 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
1828 } | 1840 } |
1829 DCHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | |
1830 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 1841 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
1831 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 1842 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
1832 } | 1843 } |
1833 } | 1844 } |
1834 | 1845 |
1835 | 1846 |
1836 void SemiSpace::Reset() { | 1847 void SemiSpace::Reset() { |
1837 DCHECK_NE(anchor_.next_page(), &anchor_); | 1848 DCHECK_NE(anchor_.next_page(), &anchor_); |
1838 current_page_ = anchor_.next_page(); | 1849 current_page_ = anchor_.next_page(); |
1839 } | 1850 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 // on from-space pages, so it might be out of sync with the marking state. | 1904 // on from-space pages, so it might be out of sync with the marking state. |
1894 if (page->heap()->incremental_marking()->IsMarking()) { | 1905 if (page->heap()->incremental_marking()->IsMarking()) { |
1895 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1906 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
1896 } else { | 1907 } else { |
1897 CHECK( | 1908 CHECK( |
1898 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1909 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
1899 } | 1910 } |
1900 // TODO(gc): Check that the live_bytes_count_ field matches the | 1911 // TODO(gc): Check that the live_bytes_count_ field matches the |
1901 // black marking on the page (if we make it match in new-space). | 1912 // black marking on the page (if we make it match in new-space). |
1902 } | 1913 } |
1903 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | |
1904 CHECK_EQ(page->prev_page()->next_page(), page); | 1914 CHECK_EQ(page->prev_page()->next_page(), page); |
1905 page = page->next_page(); | 1915 page = page->next_page(); |
1906 } | 1916 } |
1907 } | 1917 } |
1908 #endif | 1918 #endif |
1909 | 1919 |
1910 #ifdef DEBUG | 1920 #ifdef DEBUG |
1911 void SemiSpace::AssertValidRange(Address start, Address end) { | 1921 void SemiSpace::AssertValidRange(Address start, Address end) { |
1912 // Addresses belong to same semi-space | 1922 // Addresses belong to same semi-space |
1913 NewSpacePage* page = NewSpacePage::FromLimit(start); | 1923 NewSpacePage* page = NewSpacePage::FromLimit(start); |
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3238 object->ShortPrint(); | 3248 object->ShortPrint(); |
3239 PrintF("\n"); | 3249 PrintF("\n"); |
3240 } | 3250 } |
3241 printf(" --------------------------------------\n"); | 3251 printf(" --------------------------------------\n"); |
3242 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3252 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3243 } | 3253 } |
3244 | 3254 |
3245 #endif // DEBUG | 3255 #endif // DEBUG |
3246 } // namespace internal | 3256 } // namespace internal |
3247 } // namespace v8 | 3257 } // namespace v8 |
OLD | NEW |