Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: src/heap/spaces.cc

Issue 2689683002: [heap] Fix address space leak in Unmapper (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/spaces.h ('k') | src/heap/spaces-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | src/heap/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698