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 |