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 |