| 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_GT(pages, 0); |
| 943 DCHECK(nullptr == old_to_new_slots_); |
| 944 old_to_new_slots_ = new SlotSet[pages]; |
| 945 for (int 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 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 void PagedSpace::ReleasePage(Page* page, bool evict_free_list_items) { | 1244 void PagedSpace::ReleasePage(Page* page, bool evict_free_list_items) { |
| 1228 DCHECK(page->LiveBytes() == 0); | 1245 DCHECK(page->LiveBytes() == 0); |
| 1229 DCHECK(AreaSize() == page->area_size()); | 1246 DCHECK(AreaSize() == page->area_size()); |
| 1230 | 1247 |
| 1231 if (evict_free_list_items) { | 1248 if (evict_free_list_items) { |
| 1232 intptr_t size = free_list_.EvictFreeListItems(page); | 1249 intptr_t size = free_list_.EvictFreeListItems(page); |
| 1233 accounting_stats_.AllocateBytes(size); | 1250 accounting_stats_.AllocateBytes(size); |
| 1234 DCHECK_EQ(AreaSize(), static_cast<int>(size)); | 1251 DCHECK_EQ(AreaSize(), static_cast<int>(size)); |
| 1235 } | 1252 } |
| 1236 | 1253 |
| 1237 if (page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)) { | |
| 1238 heap()->decrement_scan_on_scavenge_pages(); | |
| 1239 page->ClearFlag(MemoryChunk::SCAN_ON_SCAVENGE); | |
| 1240 } | |
| 1241 | |
| 1242 DCHECK(!free_list_.ContainsPageFreeListItems(page)); | 1254 DCHECK(!free_list_.ContainsPageFreeListItems(page)); |
| 1243 | 1255 |
| 1244 if (Page::FromAllocationTop(allocation_info_.top()) == page) { | 1256 if (Page::FromAllocationTop(allocation_info_.top()) == page) { |
| 1245 allocation_info_.Reset(nullptr, nullptr); | 1257 allocation_info_.Reset(nullptr, nullptr); |
| 1246 } | 1258 } |
| 1247 | 1259 |
| 1248 // If page is still in a list, unlink it from that list. | 1260 // If page is still in a list, unlink it from that list. |
| 1249 if (page->next_chunk() != NULL) { | 1261 if (page->next_chunk() != NULL) { |
| 1250 DCHECK(page->prev_chunk() != NULL); | 1262 DCHECK(page->prev_chunk() != NULL); |
| 1251 page->Unlink(); | 1263 page->Unlink(); |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 page->SetFlags(flags, mask); | 1878 page->SetFlags(flags, mask); |
| 1867 if (becomes_to_space) { | 1879 if (becomes_to_space) { |
| 1868 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 1880 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
| 1869 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 1881 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
| 1870 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 1882 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| 1871 page->ResetLiveBytes(); | 1883 page->ResetLiveBytes(); |
| 1872 } else { | 1884 } else { |
| 1873 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 1885 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
| 1874 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 1886 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
| 1875 } | 1887 } |
| 1876 DCHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | |
| 1877 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 1888 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
| 1878 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 1889 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
| 1879 } | 1890 } |
| 1880 } | 1891 } |
| 1881 | 1892 |
| 1882 | 1893 |
| 1883 void SemiSpace::Reset() { | 1894 void SemiSpace::Reset() { |
| 1884 DCHECK_NE(anchor_.next_page(), &anchor_); | 1895 DCHECK_NE(anchor_.next_page(), &anchor_); |
| 1885 current_page_ = anchor_.next_page(); | 1896 current_page_ = anchor_.next_page(); |
| 1886 } | 1897 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 // on from-space pages, so it might be out of sync with the marking state. | 1951 // on from-space pages, so it might be out of sync with the marking state. |
| 1941 if (page->heap()->incremental_marking()->IsMarking()) { | 1952 if (page->heap()->incremental_marking()->IsMarking()) { |
| 1942 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1953 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1943 } else { | 1954 } else { |
| 1944 CHECK( | 1955 CHECK( |
| 1945 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1956 !page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1946 } | 1957 } |
| 1947 // TODO(gc): Check that the live_bytes_count_ field matches the | 1958 // TODO(gc): Check that the live_bytes_count_ field matches the |
| 1948 // black marking on the page (if we make it match in new-space). | 1959 // black marking on the page (if we make it match in new-space). |
| 1949 } | 1960 } |
| 1950 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | |
| 1951 CHECK_EQ(page->prev_page()->next_page(), page); | 1961 CHECK_EQ(page->prev_page()->next_page(), page); |
| 1952 page = page->next_page(); | 1962 page = page->next_page(); |
| 1953 } | 1963 } |
| 1954 } | 1964 } |
| 1955 #endif | 1965 #endif |
| 1956 | 1966 |
| 1957 #ifdef DEBUG | 1967 #ifdef DEBUG |
| 1958 void SemiSpace::AssertValidRange(Address start, Address end) { | 1968 void SemiSpace::AssertValidRange(Address start, Address end) { |
| 1959 // Addresses belong to same semi-space | 1969 // Addresses belong to same semi-space |
| 1960 NewSpacePage* page = NewSpacePage::FromLimit(start); | 1970 NewSpacePage* page = NewSpacePage::FromLimit(start); |
| (...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3285 object->ShortPrint(); | 3295 object->ShortPrint(); |
| 3286 PrintF("\n"); | 3296 PrintF("\n"); |
| 3287 } | 3297 } |
| 3288 printf(" --------------------------------------\n"); | 3298 printf(" --------------------------------------\n"); |
| 3289 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3299 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3290 } | 3300 } |
| 3291 | 3301 |
| 3292 #endif // DEBUG | 3302 #endif // DEBUG |
| 3293 } // namespace internal | 3303 } // namespace internal |
| 3294 } // namespace v8 | 3304 } // namespace v8 |
| OLD | NEW |