Reviewers: Michael Lippautz,

Description:
Concurrently unmap free pages.

BUG=

Please review this at https://codereview.chromium.org/1303263002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+56, -5 lines):
  M src/heap/heap.h
  M src/heap/heap.cc
  M src/heap/mark-compact.cc


Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 234bc9f563a14d148cc19967d902fb7cc1c4ff8e..0ee13ebaf4d814b5b83c7a7ac7c42a6085cc7b10 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -135,6 +135,7 @@ Heap::Heap()
       current_gc_flags_(Heap::kNoGCFlags),
       external_string_table_(this),
       chunks_queued_for_free_(NULL),
+      pending_unmap_job_semaphore_(0),
       gc_callbacks_depth_(0),
       deserialization_complete_(false),
       concurrent_sweeping_enabled_(false),
@@ -6654,6 +6655,34 @@ void ExternalStringTable::TearDown() {
 }


+class Heap::UnmapFreeMemoryTask : public v8::Task {
+ public:
+  UnmapFreeMemoryTask(Heap* heap, MemoryChunk* head)
+      : heap_(heap), head_(head) {}
+  virtual ~UnmapFreeMemoryTask() {}
+
+
+ private:
+  // v8::Task overrides.
+  void Run() override {
+    heap_->FreeQueuedChunks(head_);
+    heap_->pending_unmap_job_semaphore_.Signal();
+  }
+
+  Heap* heap_;
+  MemoryChunk* head_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnmapFreeMemoryTask);
+};
+
+
+void Heap::WaitUntilUnmappingOfFreeChunksCompleted() {
+  // We start an unmap job after sweeping and after compaction.
+  pending_unmap_job_semaphore_.Wait();
+  pending_unmap_job_semaphore_.Wait();
+}
+
+
 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
   chunk->set_next_chunk(chunks_queued_for_free_);
   chunks_queued_for_free_ = chunk;
@@ -6668,19 +6697,32 @@ void Heap::FilterStoreBufferEntriesOnAboutToBeFreedPages() {
     next = chunk->next_chunk();
     chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED);
   }
-  isolate_->heap()->store_buffer()->Compact();
-  isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
+  store_buffer()->Compact();
+  store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
 }


 void Heap::FreeQueuedChunks() {
+  if (chunks_queued_for_free_ != NULL) {
+    V8::GetCurrentPlatform()->CallOnBackgroundThread(
+        new UnmapFreeMemoryTask(this, chunks_queued_for_free_),
+        v8::Platform::kShortRunningTask);
+    chunks_queued_for_free_ = NULL;
+  } else {
+    // If we do not have anything to unmap, we just signal the semaphore
+    // that we are done.
+    pending_unmap_job_semaphore_.Signal();
+  }
+}
+
+
+void Heap::FreeQueuedChunks(MemoryChunk* list_head) {
   MemoryChunk* next;
   MemoryChunk* chunk;
-  for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
+  for (chunk = list_head; chunk != NULL; chunk = next) {
     next = chunk->next_chunk();
     isolate_->memory_allocator()->Free(chunk);
   }
-  chunks_queued_for_free_ = NULL;
 }


Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index 415e7d0c5ee569ea458263beb294efc1245cead9..88d49cff421d7389d6c7df9c8c9b7787bd32bf17 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -1442,7 +1442,9 @@ class Heap {

   void QueueMemoryChunkForFree(MemoryChunk* chunk);
   void FilterStoreBufferEntriesOnAboutToBeFreedPages();
+  void FreeQueuedChunks(MemoryChunk* list_head);
   void FreeQueuedChunks();
+  void WaitUntilUnmappingOfFreeChunksCompleted();

   int gc_count() const { return gc_count_; }

@@ -1681,6 +1683,8 @@ class Heap {
  private:
   Heap();

+  class UnmapFreeMemoryTask;
+
   int current_gc_flags() { return current_gc_flags_; }
   void set_current_gc_flags(int flags) {
     current_gc_flags_ = flags;
@@ -2299,6 +2303,8 @@ class Heap {

   MemoryChunk* chunks_queued_for_free_;

+  base::Semaphore pending_unmap_job_semaphore_;
+
   base::Mutex relocation_mutex_;

   int gc_callbacks_depth_;
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index af6894c5755b2a6d7a14a853c3d3fd1ddb83de73..4c8db42035bb8c5722fe9b2fbe73b35d87f43f54 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -519,12 +519,15 @@ void MarkCompactCollector::EnsureSweepingCompleted() {
     SweepInParallel(heap()->paged_space(CODE_SPACE), 0);
     SweepInParallel(heap()->paged_space(MAP_SPACE), 0);
   }
-  // Wait twice for both jobs.
+
   if (heap()->concurrent_sweeping_enabled()) {
     pending_sweeper_jobs_semaphore_.Wait();
     pending_sweeper_jobs_semaphore_.Wait();
     pending_sweeper_jobs_semaphore_.Wait();
   }
+
+  heap()->WaitUntilUnmappingOfFreeChunksCompleted();
+
   ParallelSweepSpacesComplete();
   sweeping_in_progress_ = false;
   RefillFreeList(heap()->paged_space(OLD_SPACE));


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to