| 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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 } | 421 } |
| 422 | 422 |
| 423 | 423 |
| 424 NewSpacePage* NewSpacePage::Initialize(Heap* heap, Address start, | 424 NewSpacePage* NewSpacePage::Initialize(Heap* heap, Address start, |
| 425 SemiSpace* semi_space) { | 425 SemiSpace* semi_space) { |
| 426 Address area_start = start + NewSpacePage::kObjectStartOffset; | 426 Address area_start = start + NewSpacePage::kObjectStartOffset; |
| 427 Address area_end = start + Page::kPageSize; | 427 Address area_end = start + Page::kPageSize; |
| 428 | 428 |
| 429 MemoryChunk* chunk = | 429 MemoryChunk* chunk = |
| 430 MemoryChunk::Initialize(heap, start, Page::kPageSize, area_start, | 430 MemoryChunk::Initialize(heap, start, Page::kPageSize, area_start, |
| 431 area_end, NOT_EXECUTABLE, semi_space); | 431 area_end, NOT_EXECUTABLE, semi_space, nullptr); |
| 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 |
| 442 | 442 |
| 443 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { | 443 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { |
| 444 set_owner(semi_space); | 444 set_owner(semi_space); |
| 445 set_next_chunk(this); | 445 set_next_chunk(this); |
| 446 set_prev_chunk(this); | 446 set_prev_chunk(this); |
| 447 // Flags marks this invalid page as not being in new-space. | 447 // Flags marks this invalid page as not being in new-space. |
| 448 // All real new-space pages will be in new-space. | 448 // All real new-space pages will be in new-space. |
| 449 SetFlags(0, ~0); | 449 SetFlags(0, ~0); |
| 450 } | 450 } |
| 451 | 451 |
| 452 | |
| 453 MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, | 452 MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, |
| 454 Address area_start, Address area_end, | 453 Address area_start, Address area_end, |
| 455 Executability executable, Space* owner) { | 454 Executability executable, Space* owner, |
| 455 base::VirtualMemory* reservation) { |
| 456 MemoryChunk* chunk = FromAddress(base); | 456 MemoryChunk* chunk = FromAddress(base); |
| 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); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 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 |
| 493 if (reservation != nullptr) { |
| 494 chunk->reservation_.TakeControl(reservation); |
| 495 } |
| 496 |
| 493 return chunk; | 497 return chunk; |
| 494 } | 498 } |
| 495 | 499 |
| 496 | 500 |
| 497 // Commit MemoryChunk area to the requested size. | 501 // Commit MemoryChunk area to the requested size. |
| 498 bool MemoryChunk::CommitArea(size_t requested) { | 502 bool MemoryChunk::CommitArea(size_t requested) { |
| 499 size_t guard_size = | 503 size_t guard_size = |
| 500 IsFlagSet(IS_EXECUTABLE) ? MemoryAllocator::CodePageGuardSize() : 0; | 504 IsFlagSet(IS_EXECUTABLE) ? MemoryAllocator::CodePageGuardSize() : 0; |
| 501 size_t header_size = area_start() - address() - guard_size; | 505 size_t header_size = area_start() - address() - guard_size; |
| 502 size_t commit_size = | 506 size_t commit_size = |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 // treat reserved but not-yet committed memory regions of chunks as allocated. | 688 // treat reserved but not-yet committed memory regions of chunks as allocated. |
| 685 isolate_->counters()->memory_allocated()->Increment( | 689 isolate_->counters()->memory_allocated()->Increment( |
| 686 static_cast<int>(chunk_size)); | 690 static_cast<int>(chunk_size)); |
| 687 | 691 |
| 688 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size)); | 692 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size)); |
| 689 if (owner != NULL) { | 693 if (owner != NULL) { |
| 690 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); | 694 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); |
| 691 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); | 695 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); |
| 692 } | 696 } |
| 693 | 697 |
| 694 MemoryChunk* result = MemoryChunk::Initialize( | 698 return MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end, |
| 695 heap, base, chunk_size, area_start, area_end, executable, owner); | 699 executable, owner, &reservation); |
| 696 result->set_reserved_memory(&reservation); | |
| 697 return result; | |
| 698 } | 700 } |
| 699 | 701 |
| 700 | 702 |
| 701 void Page::ResetFreeListStatistics() { | 703 void Page::ResetFreeListStatistics() { |
| 702 non_available_small_blocks_ = 0; | 704 non_available_small_blocks_ = 0; |
| 703 available_in_small_free_list_ = 0; | 705 available_in_small_free_list_ = 0; |
| 704 available_in_medium_free_list_ = 0; | 706 available_in_medium_free_list_ = 0; |
| 705 available_in_large_free_list_ = 0; | 707 available_in_large_free_list_ = 0; |
| 706 available_in_huge_free_list_ = 0; | 708 available_in_huge_free_list_ = 0; |
| 707 } | 709 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 } | 915 } |
| 914 vm->Uncommit(header, header_size); | 916 vm->Uncommit(header, header_size); |
| 915 } | 917 } |
| 916 return false; | 918 return false; |
| 917 } | 919 } |
| 918 | 920 |
| 919 | 921 |
| 920 // ----------------------------------------------------------------------------- | 922 // ----------------------------------------------------------------------------- |
| 921 // MemoryChunk implementation | 923 // MemoryChunk implementation |
| 922 | 924 |
| 923 void MemoryChunk::IncrementLiveBytesFromMutator(HeapObject* object, int by) { | |
| 924 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | |
| 925 if (!chunk->InNewSpace() && !static_cast<Page*>(chunk)->SweepingDone()) { | |
| 926 static_cast<PagedSpace*>(chunk->owner())->Allocate(by); | |
| 927 } | |
| 928 chunk->IncrementLiveBytes(by); | |
| 929 } | |
| 930 | |
| 931 | |
| 932 void MemoryChunk::ReleaseAllocatedMemory() { | 925 void MemoryChunk::ReleaseAllocatedMemory() { |
| 933 delete slots_buffer_; | 926 delete slots_buffer_; |
| 927 slots_buffer_ = nullptr; |
| 934 delete skip_list_; | 928 delete skip_list_; |
| 929 skip_list_ = nullptr; |
| 935 delete mutex_; | 930 delete mutex_; |
| 931 mutex_ = nullptr; |
| 936 ReleaseOldToNewSlots(); | 932 ReleaseOldToNewSlots(); |
| 937 } | 933 } |
| 938 | 934 |
| 939 void MemoryChunk::AllocateOldToNewSlots() { | 935 void MemoryChunk::AllocateOldToNewSlots() { |
| 940 size_t pages = (size_ + Page::kPageSize - 1) / Page::kPageSize; | 936 size_t pages = (size_ + Page::kPageSize - 1) / Page::kPageSize; |
| 941 DCHECK(owner() == heap_->lo_space() || pages == 1); | 937 DCHECK(owner() == heap_->lo_space() || pages == 1); |
| 942 DCHECK(pages > 0); | 938 DCHECK(pages > 0); |
| 943 DCHECK(nullptr == old_to_new_slots_); | 939 DCHECK(nullptr == old_to_new_slots_); |
| 944 old_to_new_slots_ = new SlotSet[pages]; | 940 old_to_new_slots_ = new SlotSet[pages]; |
| 945 for (size_t i = 0; i < pages; i++) { | 941 for (size_t i = 0; i < pages; i++) { |
| (...skipping 2288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3234 object->ShortPrint(); | 3230 object->ShortPrint(); |
| 3235 PrintF("\n"); | 3231 PrintF("\n"); |
| 3236 } | 3232 } |
| 3237 printf(" --------------------------------------\n"); | 3233 printf(" --------------------------------------\n"); |
| 3238 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3234 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3239 } | 3235 } |
| 3240 | 3236 |
| 3241 #endif // DEBUG | 3237 #endif // DEBUG |
| 3242 } // namespace internal | 3238 } // namespace internal |
| 3243 } // namespace v8 | 3239 } // namespace v8 |
| OLD | NEW |