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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 // Non-regular chunks. | 375 // Non-regular chunks. |
376 while ((chunk = GetMemoryChunkSafe<kNonRegular>()) != nullptr) { | 376 while ((chunk = GetMemoryChunkSafe<kNonRegular>()) != nullptr) { |
377 allocator_->PerformFreeMemory(chunk); | 377 allocator_->PerformFreeMemory(chunk); |
378 } | 378 } |
379 } | 379 } |
380 | 380 |
381 void MemoryAllocator::Unmapper::TearDown() { | 381 void MemoryAllocator::Unmapper::TearDown() { |
382 WaitUntilCompleted(); | 382 WaitUntilCompleted(); |
383 ReconsiderDelayedChunks(); | 383 ReconsiderDelayedChunks(); |
384 CHECK(delayed_regular_chunks_.empty()); | 384 CHECK(delayed_regular_chunks_.empty()); |
385 PerformFreeMemoryOnQueuedChunks(); | 385 // Free any queued chunks. Note that we need to clear the pooled flag for |
386 // regular chunks as they otherwise only get uncommitted. | |
387 MemoryChunk* chunk = nullptr; | |
Hannes Payer (out of office)
2017/02/10 12:29:22
Let's wrap that into a function with a proper name
Michael Lippautz
2017/02/10 13:34:12
Done. Unified into a single function.
| |
388 while ((chunk = GetMemoryChunkSafe<kRegular>()) != nullptr) { | |
389 chunk->ClearFlag(MemoryChunk::POOLED); | |
390 allocator_->PerformFreeMemory(chunk); | |
391 } | |
392 while ((chunk = GetMemoryChunkSafe<kPooled>()) != nullptr) { | |
393 // Already uncommitted memory. | |
394 allocator_->Free<MemoryAllocator::kAlreadyPooled>(chunk); | |
395 } | |
396 while ((chunk = GetMemoryChunkSafe<kNonRegular>()) != nullptr) { | |
397 allocator_->PerformFreeMemory(chunk); | |
398 } | |
Hannes Payer (out of office)
2017/02/10 12:29:22
Let's verify here that all lists are empty.
Michael Lippautz
2017/02/10 13:34:12
Done.
| |
386 } | 399 } |
387 | 400 |
388 void MemoryAllocator::Unmapper::ReconsiderDelayedChunks() { | 401 void MemoryAllocator::Unmapper::ReconsiderDelayedChunks() { |
389 std::list<MemoryChunk*> delayed_chunks(std::move(delayed_regular_chunks_)); | 402 std::list<MemoryChunk*> delayed_chunks(std::move(delayed_regular_chunks_)); |
390 // Move constructed, so the permanent list should be empty. | 403 // Move constructed, so the permanent list should be empty. |
391 DCHECK(delayed_regular_chunks_.empty()); | 404 DCHECK(delayed_regular_chunks_.empty()); |
392 for (auto it = delayed_chunks.begin(); it != delayed_chunks.end(); ++it) { | 405 for (auto it = delayed_chunks.begin(); it != delayed_chunks.end(); ++it) { |
393 AddMemoryChunkSafe<kRegular>(*it); | 406 AddMemoryChunkSafe<kRegular>(*it); |
394 } | 407 } |
395 } | 408 } |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
902 } | 915 } |
903 } | 916 } |
904 | 917 |
905 template <MemoryAllocator::FreeMode mode> | 918 template <MemoryAllocator::FreeMode mode> |
906 void MemoryAllocator::Free(MemoryChunk* chunk) { | 919 void MemoryAllocator::Free(MemoryChunk* chunk) { |
907 switch (mode) { | 920 switch (mode) { |
908 case kFull: | 921 case kFull: |
909 PreFreeMemory(chunk); | 922 PreFreeMemory(chunk); |
910 PerformFreeMemory(chunk); | 923 PerformFreeMemory(chunk); |
911 break; | 924 break; |
925 case kAlreadyPooled: | |
926 // Pooled pages cannot be touched anymore as their memory is uncommitted. | |
927 FreeMemory(chunk->address(), static_cast<size_t>(MemoryChunk::kPageSize), | |
928 Executability::NOT_EXECUTABLE); | |
929 break; | |
912 case kPooledAndQueue: | 930 case kPooledAndQueue: |
913 DCHECK_EQ(chunk->size(), static_cast<size_t>(MemoryChunk::kPageSize)); | 931 DCHECK_EQ(chunk->size(), static_cast<size_t>(MemoryChunk::kPageSize)); |
914 DCHECK_EQ(chunk->executable(), NOT_EXECUTABLE); | 932 DCHECK_EQ(chunk->executable(), NOT_EXECUTABLE); |
915 chunk->SetFlag(MemoryChunk::POOLED); | 933 chunk->SetFlag(MemoryChunk::POOLED); |
916 // Fall through to kPreFreeAndQueue. | 934 // Fall through to kPreFreeAndQueue. |
917 case kPreFreeAndQueue: | 935 case kPreFreeAndQueue: |
918 PreFreeMemory(chunk); | 936 PreFreeMemory(chunk); |
919 // The chunks added to this queue will be freed by a concurrent thread. | 937 // The chunks added to this queue will be freed by a concurrent thread. |
920 unmapper()->AddMemoryChunkSafe(chunk); | 938 unmapper()->AddMemoryChunkSafe(chunk); |
921 break; | 939 break; |
922 default: | |
923 UNREACHABLE(); | |
924 } | 940 } |
925 } | 941 } |
926 | 942 |
927 template void MemoryAllocator::Free<MemoryAllocator::kFull>(MemoryChunk* chunk); | 943 template void MemoryAllocator::Free<MemoryAllocator::kFull>(MemoryChunk* chunk); |
928 | 944 |
945 template void MemoryAllocator::Free<MemoryAllocator::kAlreadyPooled>( | |
946 MemoryChunk* chunk); | |
947 | |
929 template void MemoryAllocator::Free<MemoryAllocator::kPreFreeAndQueue>( | 948 template void MemoryAllocator::Free<MemoryAllocator::kPreFreeAndQueue>( |
930 MemoryChunk* chunk); | 949 MemoryChunk* chunk); |
931 | 950 |
932 template void MemoryAllocator::Free<MemoryAllocator::kPooledAndQueue>( | 951 template void MemoryAllocator::Free<MemoryAllocator::kPooledAndQueue>( |
933 MemoryChunk* chunk); | 952 MemoryChunk* chunk); |
934 | 953 |
935 template <MemoryAllocator::AllocationMode alloc_mode, typename SpaceType> | |
936 Page* MemoryAllocator::AllocatePage(size_t size, SpaceType* owner, | |
937 Executability executable) { | |
938 MemoryChunk* chunk = nullptr; | |
939 if (alloc_mode == kPooled) { | |
940 DCHECK_EQ(size, static_cast<size_t>(MemoryChunk::kAllocatableMemory)); | |
941 DCHECK_EQ(executable, NOT_EXECUTABLE); | |
942 chunk = AllocatePagePooled(owner); | |
943 } | |
944 if (chunk == nullptr) { | |
945 chunk = AllocateChunk(size, size, executable, owner); | |
946 } | |
947 if (chunk == nullptr) return nullptr; | |
948 return Page::Initialize(isolate_->heap(), chunk, executable, owner); | |
949 } | |
950 | |
951 template Page* | |
952 MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, PagedSpace>( | |
953 size_t size, PagedSpace* owner, Executability executable); | |
954 template Page* | |
955 MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, SemiSpace>( | |
956 size_t size, SemiSpace* owner, Executability executable); | |
957 template Page* | |
958 MemoryAllocator::AllocatePage<MemoryAllocator::kPooled, SemiSpace>( | |
959 size_t size, SemiSpace* owner, Executability executable); | |
960 | |
961 LargePage* MemoryAllocator::AllocateLargePage(size_t size, | 954 LargePage* MemoryAllocator::AllocateLargePage(size_t size, |
962 LargeObjectSpace* owner, | 955 LargeObjectSpace* owner, |
963 Executability executable) { | 956 Executability executable) { |
964 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); | 957 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); |
965 if (chunk == nullptr) return nullptr; | 958 if (chunk == nullptr) return nullptr; |
966 return LargePage::Initialize(isolate_->heap(), chunk, executable, owner); | 959 return LargePage::Initialize(isolate_->heap(), chunk, executable, owner); |
967 } | 960 } |
968 | 961 |
969 template <typename SpaceType> | 962 template <typename SpaceType> |
970 MemoryChunk* MemoryAllocator::AllocatePagePooled(SpaceType* owner) { | 963 MemoryChunk* MemoryAllocator::AllocatePagePooled(SpaceType* owner) { |
(...skipping 2259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3230 object->ShortPrint(); | 3223 object->ShortPrint(); |
3231 PrintF("\n"); | 3224 PrintF("\n"); |
3232 } | 3225 } |
3233 printf(" --------------------------------------\n"); | 3226 printf(" --------------------------------------\n"); |
3234 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3227 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3235 } | 3228 } |
3236 | 3229 |
3237 #endif // DEBUG | 3230 #endif // DEBUG |
3238 } // namespace internal | 3231 } // namespace internal |
3239 } // namespace v8 | 3232 } // namespace v8 |
OLD | NEW |