[heap] Implement concurrent marking boilerplate.

This patch adds a trivial ConcurrentMarking class that can start
background tasks.

BUG=chromium:694255

Review-Url: https://codereview.chromium.org/2728363002
Cr-Commit-Position: refs/heads/master@{#43615}
This commit is contained in:
ulan 2017-03-06 07:19:36 -08:00 committed by Commit bot
parent 3c63c40f3e
commit e96b5ed423
10 changed files with 179 additions and 2 deletions

View File

@ -1431,6 +1431,8 @@ v8_source_set("v8_base") {
"src/heap/array-buffer-tracker.h",
"src/heap/code-stats.cc",
"src/heap/code-stats.h",
"src/heap/concurrent-marking.cc",
"src/heap/concurrent-marking.h",
"src/heap/embedder-tracing.cc",
"src/heap/embedder-tracing.h",
"src/heap/gc-idle-time-handler.cc",

View File

@ -647,6 +647,7 @@ DEFINE_BOOL(age_code, true,
DEFINE_BOOL(incremental_marking, true, "use incremental marking")
DEFINE_BOOL(incremental_marking_wrappers, true,
"use incremental marking for marking wrappers")
DEFINE_BOOL(concurrent_marking, false, "use concurrent marking")
DEFINE_INT(min_progress_during_incremental_marking_finalization, 32,
"keep finalizing incremental marking as long as we discover at "
"least this many unmarked objects")

View File

@ -0,0 +1,81 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/heap/concurrent-marking.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/isolate.h"
#include "src/locked-queue-inl.h"
#include "src/v8.h"
namespace v8 {
namespace internal {
class ConcurrentMarking::Task : public CancelableTask {
public:
Task(Heap* heap, Queue* queue, base::Semaphore* on_finish)
: CancelableTask(heap->isolate()),
heap_(heap),
queue_(queue),
on_finish_(on_finish) {}
virtual ~Task() {}
private:
// v8::internal::CancelableTask overrides.
void RunInternal() override {
USE(heap_);
HeapObject* object;
while (queue_->Dequeue(&object)) {
// TODO(ulan): Implement actual marking.
}
on_finish_->Signal();
}
Heap* heap_;
Queue* queue_;
base::Semaphore* on_finish_;
DISALLOW_COPY_AND_ASSIGN(Task);
};
ConcurrentMarking::ConcurrentMarking(Heap* heap)
: heap_(heap), pending_tasks_(0), number_of_tasks_(0) {}
ConcurrentMarking::~ConcurrentMarking() {}
void ConcurrentMarking::EnqueueObject(HeapObject* object) {
queue_.Enqueue(object);
}
bool ConcurrentMarking::IsQueueEmpty() { return queue_.IsEmpty(); }
void ConcurrentMarking::StartMarkingTasks(int number_of_tasks) {
if (!FLAG_concurrent_marking) return;
DCHECK_EQ(0, number_of_tasks_);
number_of_tasks_ = number_of_tasks;
for (int i = 0; i < number_of_tasks; i++) {
V8::GetCurrentPlatform()->CallOnBackgroundThread(
new Task(heap_, &queue_, &pending_tasks_),
v8::Platform::kShortRunningTask);
}
}
void ConcurrentMarking::WaitForTasksToComplete() {
if (!FLAG_concurrent_marking) return;
CancelableTaskManager* cancelable_task_manager =
heap_->isolate()->cancelable_task_manager();
for (int i = 0; i < number_of_tasks_; i++) {
if (cancelable_task_manager->TryAbort(task_ids_[i]) !=
CancelableTaskManager::kTaskAborted) {
pending_tasks_.Wait();
}
}
number_of_tasks_ = 0;
}
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,48 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_CONCURRENT_MARKING_
#define V8_HEAP_CONCURRENT_MARKING_
#include "src/allocation.h"
#include "src/cancelable-task.h"
#include "src/locked-queue.h"
#include "src/utils.h"
#include "src/v8.h"
namespace v8 {
namespace internal {
class Heap;
class Isolate;
class ConcurrentMarking {
public:
static const int kMaxNumberOfTasks = 10;
explicit ConcurrentMarking(Heap* heap);
~ConcurrentMarking();
void EnqueueObject(HeapObject* object);
bool IsQueueEmpty();
void StartMarkingTasks(int number_of_tasks);
void WaitForTasksToComplete();
private:
class Task;
// TODO(ulan): Replace with faster queue.
typedef LockedQueue<HeapObject*> Queue;
Heap* heap_;
base::Semaphore pending_tasks_;
Queue queue_;
int number_of_tasks_;
uint32_t task_ids_[kMaxNumberOfTasks];
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_PAGE_PARALLEL_JOB_

View File

@ -22,6 +22,7 @@
#include "src/global-handles.h"
#include "src/heap/array-buffer-tracker-inl.h"
#include "src/heap/code-stats.h"
#include "src/heap/concurrent-marking.h"
#include "src/heap/embedder-tracing.h"
#include "src/heap/gc-idle-time-handler.h"
#include "src/heap/gc-tracer.h"
@ -135,6 +136,7 @@ Heap::Heap()
memory_allocator_(nullptr),
store_buffer_(nullptr),
incremental_marking_(nullptr),
concurrent_marking_(nullptr),
gc_idle_time_handler_(nullptr),
memory_reducer_(nullptr),
live_object_stats_(nullptr),
@ -5500,12 +5502,12 @@ bool Heap::SetUp() {
code_range_size_))
return false;
// Initialize store buffer.
store_buffer_ = new StoreBuffer(this);
// Initialize incremental marking.
incremental_marking_ = new IncrementalMarking(this);
concurrent_marking_ = new ConcurrentMarking(this);
for (int i = 0; i <= LAST_SPACE; i++) {
space_[i] = nullptr;
}
@ -5690,6 +5692,9 @@ void Heap::TearDown() {
delete incremental_marking_;
incremental_marking_ = nullptr;
delete concurrent_marking_;
concurrent_marking_ = nullptr;
delete gc_idle_time_handler_;
gc_idle_time_handler_ = nullptr;

View File

@ -318,6 +318,7 @@ using v8::MemoryPressureLevel;
// Forward declarations.
class AllocationObserver;
class ArrayBufferTracker;
class ConcurrentMarking;
class GCIdleTimeAction;
class GCIdleTimeHandler;
class GCIdleTimeHeapState;
@ -2290,6 +2291,7 @@ class Heap {
StoreBuffer* store_buffer_;
IncrementalMarking* incremental_marking_;
ConcurrentMarking* concurrent_marking_;
GCIdleTimeHandler* gc_idle_time_handler_;
@ -2373,6 +2375,7 @@ class Heap {
// Classes in "heap" can be friends.
friend class AlwaysAllocateScope;
friend class ConcurrentMarking;
friend class GCCallbacksScope;
friend class GCTracer;
friend class HeapIterator;

View File

@ -933,6 +933,8 @@
'heap/array-buffer-tracker.h',
'heap/code-stats.cc',
'heap/code-stats.h',
'heap/concurrent-marking.cc',
'heap/concurrent-marking.h',
'heap/embedder-tracing.cc',
'heap/embedder-tracing.h',
'heap/memory-reducer.cc',

View File

@ -73,6 +73,7 @@ v8_executable("cctest") {
"heap/test-alloc.cc",
"heap/test-array-buffer-tracker.cc",
"heap/test-compaction.cc",
"heap/test-concurrent-marking.cc",
"heap/test-heap.cc",
"heap/test-incremental-marking.cc",
"heap/test-lab.cc",

View File

@ -104,6 +104,7 @@
'heap/test-alloc.cc',
'heap/test-array-buffer-tracker.cc',
'heap/test-compaction.cc',
'heap/test-concurrent-marking.cc',
'heap/test-heap.cc',
'heap/test-incremental-marking.cc',
'heap/test-lab.cc',

View File

@ -0,0 +1,33 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdlib.h>
#include "src/v8.h"
#include "src/heap/concurrent-marking.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
namespace v8 {
namespace internal {
TEST(ConcurrentMarking) {
i::FLAG_concurrent_marking = true;
CcTest::InitializeVM();
Heap* heap = CcTest::heap();
ConcurrentMarking* concurrent_marking = new ConcurrentMarking(heap);
for (int i = 0; i < 10; i++) {
concurrent_marking->EnqueueObject(heap->undefined_value());
}
concurrent_marking->StartMarkingTasks(3);
while (!concurrent_marking->IsQueueEmpty()) {
}
concurrent_marking->WaitForTasksToComplete();
delete concurrent_marking;
}
} // namespace internal
} // namespace v8