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

Unified Diff: src/heap/spaces.h

Issue 1913083002: [heap] Uncommit pooled pages concurrently (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/spaces.h
diff --git a/src/heap/spaces.h b/src/heap/spaces.h
index 791ee6c32ac410b63ff4de43ab2d27eec113a4dd..0a1fcc871ef755bf2e81f44c14bedd79c19a6c77 100644
--- a/src/heap/spaces.h
+++ b/src/heap/spaces.h
@@ -5,6 +5,8 @@
#ifndef V8_HEAP_SPACES_H_
#define V8_HEAP_SPACES_H_
+#include <list>
+
#include "src/allocation.h"
#include "src/atomic-utils.h"
#include "src/base/atomicops.h"
@@ -441,6 +443,10 @@ class MemoryChunk {
// still has to be performed.
PRE_FREED,
+ // |POOLED|: When actually freeing this chunk, only uncommit and do not
+ // give up the reservation as we still reuse the chunk at some point.
+ POOLED,
+
// |COMPACTION_WAS_ABORTED|: Indicates that the compaction in this page
// has been aborted and needs special handling by the sweeper.
COMPACTION_WAS_ABORTED,
@@ -1256,15 +1262,92 @@ class SkipList {
// A space acquires chunks of memory from the operating system. The memory
// allocator allocated and deallocates pages for the paged heap spaces and large
// pages for large object space.
-//
-// Each space has to manage it's own pages.
-//
class MemoryAllocator {
public:
+ // Unmapper takes care of concurrently unmapping and uncommitting memory
+ // chunks.
+ class Unmapper {
+ public:
+ class UnmapFreeMemoryTask;
+
+ explicit Unmapper(MemoryAllocator* allocator)
+ : allocator_(allocator),
+ pending_unmapping_tasks_semaphore_(0),
+ concurrent_unmapping_tasks_active_(0) {}
+
+ void AddMemoryChunkSafe(MemoryChunk* chunk) {
+ if ((chunk->size() == Page::kPageSize) &&
+ (chunk->executable() == EXECUTABLE)) {
+ AddMemoryChunkSafe<kRegular>(chunk);
+ } else {
+ AddMemoryChunkSafe<kNonRegular>(chunk);
+ }
+ }
+
+ MemoryChunk* TryGetPooledMemoryChunkSafe() {
+ // Procedure:
+ // (1) Try to get a chunk that was declared as pooled and already has
+ // been uncommitted.
+ // (2) Try to steal any memory chunk of kPageSize that would've been
+ // unmapped.
+ MemoryChunk* chunk = GetMemoryChunkSafe<kPooled>();
+ if (chunk == nullptr) {
+ chunk = GetMemoryChunkSafe<kRegular>();
+ if (chunk != nullptr) {
+ // For stolen chunks we need to manually free any allocated memory.
+ chunk->ReleaseAllocatedMemory();
+ }
+ }
+ return chunk;
+ }
+
+ void FreeQueuedChunks();
+ bool WaitUntilCompleted();
+
+ private:
+ enum ChunkQueueType {
+ kRegular, // Pages of kPageSize that do not live in a CodeRange and
+ // can thus be used for stealing.
+ kNonRegular, // Large chunks and executable chunks.
+ kPooled, // Pooled chunks, already uncommited and ready for reuse.
+ kNumberOfChunkQueues,
+ };
+
+ template <ChunkQueueType type>
+ void AddMemoryChunkSafe(MemoryChunk* chunk) {
+ base::LockGuard<base::Mutex> guard(&mutex_);
+ chunks_[type].push_back(chunk);
+ }
+
+ template <ChunkQueueType type>
+ MemoryChunk* GetMemoryChunkSafe() {
+ base::LockGuard<base::Mutex> guard(&mutex_);
+ if (chunks_[type].empty()) return nullptr;
+ MemoryChunk* chunk = chunks_[type].front();
+ chunks_[type].pop_front();
+ return chunk;
+ }
+
+ void PerformFreeMemoryOnQueuedChunks();
+
+ base::Mutex mutex_;
+ MemoryAllocator* allocator_;
+ std::list<MemoryChunk*> chunks_[kNumberOfChunkQueues];
+ base::Semaphore pending_unmapping_tasks_semaphore_;
+ intptr_t concurrent_unmapping_tasks_active_;
+
+ friend class MemoryAllocator;
+ };
+
enum AllocationMode {
kRegular,
kPooled,
};
+ enum FreeMode {
+ kFull,
+ kPreFreeAndQueue,
+ kPooledAndQueue,
+ };
explicit MemoryAllocator(Isolate* isolate);
@@ -1283,16 +1366,7 @@ class MemoryAllocator {
PageType* AllocatePage(intptr_t size, SpaceType* owner,
Executability executable);
- // PreFree logically frees the object, i.e., it takes care of the size
- // bookkeeping and calls the allocation callback.
- void PreFreeMemory(MemoryChunk* chunk);
-
- // FreeMemory can be called concurrently when PreFree was executed before.
- void PerformFreeMemory(MemoryChunk* chunk);
-
- // Free is a wrapper method. For kRegular AllocationMode it calls PreFree and
- // PerformFreeMemory together. For kPooled it will dispatch to pooled free.
- template <MemoryAllocator::AllocationMode mode = kRegular>
+ template <MemoryAllocator::FreeMode mode = kFull>
void Free(MemoryChunk* chunk);
// Returns allocated spaces in bytes.
@@ -1398,16 +1472,21 @@ class MemoryAllocator {
size_t reserved_size);
CodeRange* code_range() { return code_range_; }
+ Unmapper* unmapper() { return &unmapper_; }
private:
+ // PreFree logically frees the object, i.e., it takes care of the size
+ // bookkeeping and calls the allocation callback.
+ void PreFreeMemory(MemoryChunk* chunk);
+
+ // FreeMemory can be called concurrently when PreFree was executed before.
+ void PerformFreeMemory(MemoryChunk* chunk);
+
// See AllocatePage for public interface. Note that currently we only support
// pools for NOT_EXECUTABLE pages of size MemoryChunk::kPageSize.
template <typename SpaceType>
MemoryChunk* AllocatePagePooled(SpaceType* owner);
- // Free that chunk into the pool.
- void FreePooled(MemoryChunk* chunk);
-
Isolate* isolate_;
CodeRange* code_range_;
@@ -1463,9 +1542,8 @@ class MemoryAllocator {
} while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high));
}
- List<MemoryChunk*> chunk_pool_;
-
base::VirtualMemory last_chunk_;
+ Unmapper unmapper_;
friend class TestCodeRangeScope;
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698