Skip to content

Commit

Permalink
deps: backport f9c4b7a from upstream V8
Browse files Browse the repository at this point in the history
Original commit message:

  [heap] Move UnmapFreeMemoryTask to CancelableTask
  This mitigates the problem of blocking on the main thread when the
  platform is unable to execute background tasks in a timely manner.

  Bug: v8:6671
  Change-Id: I741d4b7594e8d62721dad32cbfb19551ffacd0c3
  Reviewed-on: https://chromium-review.googlesource.com/599528
  Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
  Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
  Cr-Commit-Position: refs/heads/master@{#47126}

PR-URL: #14001
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
Matt Loring authored and MylesBorins committed Sep 12, 2017
1 parent b7f7d67 commit 55eed60
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 21 deletions.
2 changes: 2 additions & 0 deletions deps/v8/src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ Heap::Heap()
heap_iterator_depth_(0),
local_embedder_heap_tracer_(nullptr),
fast_promotion_mode_(false),
use_tasks_(true),
force_oom_(false),
delay_sweeper_tasks_for_testing_(false),
pending_layout_change_object_(nullptr) {
Expand Down Expand Up @@ -5823,6 +5824,7 @@ void Heap::RegisterExternallyReferencedObject(Object** object) {
}

void Heap::TearDown() {
use_tasks_ = false;
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,8 @@ class Heap {
// Returns whether SetUp has been called.
bool HasBeenSetUp();

bool use_tasks() const { return use_tasks_; }

// ===========================================================================
// Getters for spaces. =======================================================
// ===========================================================================
Expand Down Expand Up @@ -2375,6 +2377,8 @@ class Heap {

bool fast_promotion_mode_;

bool use_tasks_;

// Used for testing purposes.
bool force_oom_;
bool delay_sweeper_tasks_for_testing_;
Expand Down
40 changes: 23 additions & 17 deletions deps/v8/src/heap/spaces.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ MemoryAllocator::MemoryAllocator(Isolate* isolate)
size_executable_(0),
lowest_ever_allocated_(reinterpret_cast<void*>(-1)),
highest_ever_allocated_(reinterpret_cast<void*>(0)),
unmapper_(this) {}
unmapper_(isolate->heap(), this) {}

bool MemoryAllocator::SetUp(size_t capacity, size_t code_range_size) {
capacity_ = RoundUp(capacity, Page::kPageSize);
Expand Down Expand Up @@ -332,40 +332,46 @@ void MemoryAllocator::TearDown() {
code_range_ = nullptr;
}

class MemoryAllocator::Unmapper::UnmapFreeMemoryTask : public v8::Task {
class MemoryAllocator::Unmapper::UnmapFreeMemoryTask : public CancelableTask {
public:
explicit UnmapFreeMemoryTask(Unmapper* unmapper) : unmapper_(unmapper) {}
explicit UnmapFreeMemoryTask(Isolate* isolate, Unmapper* unmapper)
: CancelableTask(isolate), unmapper_(unmapper) {}

private:
// v8::Task overrides.
void Run() override {
void RunInternal() override {
unmapper_->PerformFreeMemoryOnQueuedChunks<FreeMode::kUncommitPooled>();
unmapper_->pending_unmapping_tasks_semaphore_.Signal();
}

Unmapper* unmapper_;
Unmapper* const unmapper_;
DISALLOW_COPY_AND_ASSIGN(UnmapFreeMemoryTask);
};

void MemoryAllocator::Unmapper::FreeQueuedChunks() {
ReconsiderDelayedChunks();
if (FLAG_concurrent_sweeping) {
if (heap_->use_tasks() && FLAG_concurrent_sweeping) {
if (concurrent_unmapping_tasks_active_ >= kMaxUnmapperTasks) {
// kMaxUnmapperTasks are already running. Avoid creating any more.
return;
}
UnmapFreeMemoryTask* task = new UnmapFreeMemoryTask(heap_->isolate(), this);
DCHECK_LT(concurrent_unmapping_tasks_active_, kMaxUnmapperTasks);
task_ids_[concurrent_unmapping_tasks_active_++] = task->id();
V8::GetCurrentPlatform()->CallOnBackgroundThread(
new UnmapFreeMemoryTask(this), v8::Platform::kShortRunningTask);
concurrent_unmapping_tasks_active_++;
task, v8::Platform::kShortRunningTask);
} else {
PerformFreeMemoryOnQueuedChunks<FreeMode::kUncommitPooled>();
}
}

bool MemoryAllocator::Unmapper::WaitUntilCompleted() {
bool waited = false;
while (concurrent_unmapping_tasks_active_ > 0) {
pending_unmapping_tasks_semaphore_.Wait();
concurrent_unmapping_tasks_active_--;
waited = true;
void MemoryAllocator::Unmapper::WaitUntilCompleted() {
for (int i = 0; i < concurrent_unmapping_tasks_active_; i++) {
if (heap_->isolate()->cancelable_task_manager()->TryAbort(task_ids_[i]) !=
CancelableTaskManager::kTaskAborted) {
pending_unmapping_tasks_semaphore_.Wait();
}
concurrent_unmapping_tasks_active_ = 0;
}
return waited;
}

template <MemoryAllocator::Unmapper::FreeMode mode>
Expand All @@ -392,7 +398,7 @@ void MemoryAllocator::Unmapper::PerformFreeMemoryOnQueuedChunks() {
}

void MemoryAllocator::Unmapper::TearDown() {
WaitUntilCompleted();
CHECK_EQ(0, concurrent_unmapping_tasks_active_);
ReconsiderDelayedChunks();
CHECK(delayed_regular_chunks_.empty());
PerformFreeMemoryOnQueuedChunks<FreeMode::kReleasePooled>();
Expand Down
13 changes: 9 additions & 4 deletions deps/v8/src/heap/spaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "src/base/bits.h"
#include "src/base/hashmap.h"
#include "src/base/platform/mutex.h"
#include "src/cancelable-task.h"
#include "src/flags.h"
#include "src/globals.h"
#include "src/heap/heap.h"
Expand Down Expand Up @@ -1149,8 +1150,9 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
public:
class UnmapFreeMemoryTask;

explicit Unmapper(MemoryAllocator* allocator)
: allocator_(allocator),
Unmapper(Heap* heap, MemoryAllocator* allocator)
: heap_(heap),
allocator_(allocator),
pending_unmapping_tasks_semaphore_(0),
concurrent_unmapping_tasks_active_(0) {
chunks_[kRegular].reserve(kReservedQueueingSlots);
Expand Down Expand Up @@ -1184,13 +1186,14 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
}

void FreeQueuedChunks();
bool WaitUntilCompleted();
void WaitUntilCompleted();
void TearDown();

bool has_delayed_chunks() { return delayed_regular_chunks_.size() > 0; }

private:
static const int kReservedQueueingSlots = 64;
static const int kMaxUnmapperTasks = 24;

enum ChunkQueueType {
kRegular, // Pages of kPageSize that do not live in a CodeRange and
Expand Down Expand Up @@ -1229,13 +1232,15 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
template <FreeMode mode>
void PerformFreeMemoryOnQueuedChunks();

Heap* const heap_;
MemoryAllocator* const allocator_;
base::Mutex mutex_;
MemoryAllocator* allocator_;
std::vector<MemoryChunk*> chunks_[kNumberOfChunkQueues];
// Delayed chunks cannot be processed in the current unmapping cycle because
// of dependencies such as an active sweeper.
// See MemoryAllocator::CanFreeMemoryChunk.
std::list<MemoryChunk*> delayed_regular_chunks_;
CancelableTaskManager::Id task_ids_[kMaxUnmapperTasks];
base::Semaphore pending_unmapping_tasks_semaphore_;
intptr_t concurrent_unmapping_tasks_active_;

Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2455,6 +2455,7 @@ void Isolate::Deinit() {
}

heap_.mark_compact_collector()->EnsureSweepingCompleted();
heap_.memory_allocator()->unmapper()->WaitUntilCompleted();

DumpAndResetStats();

Expand Down
1 change: 1 addition & 0 deletions deps/v8/test/cctest/heap/test-spaces.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ TEST(NewSpace) {
}

new_space.TearDown();
memory_allocator->unmapper()->WaitUntilCompleted();
memory_allocator->TearDown();
delete memory_allocator;
}
Expand Down

0 comments on commit 55eed60

Please sign in to comment.