Commit 2e70adc7 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Add thread-safe counter that tracks bytes marked concurrently.

Each concurrent marking task maintains task_state[i]->marked_bytes.
When a task finishes, its local counter is flushed into global
total_marked_bytes_ atomic counter.

Bug: chromium:694255
Change-Id: I629467385e80bf229e06a4231673ceb5ef8e4aea
Reviewed-on: https://chromium-review.googlesource.com/704823
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48374}
parent 2a5dc0b3
......@@ -353,7 +353,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
ConcurrentMarkingVisitor visitor(shared_, bailout_, live_bytes, weak_objects_,
task_id);
double time_ms;
size_t total_bytes_marked = 0;
size_t marked_bytes = 0;
if (FLAG_trace_concurrent_marking) {
heap_->isolate()->PrintWithTimestamp(
"Starting concurrent marking task %d\n", task_id);
......@@ -363,9 +363,9 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
bool done = false;
while (!done) {
base::LockGuard<base::Mutex> guard(&task_state->lock);
size_t bytes_marked = 0;
size_t current_marked_bytes = 0;
int objects_processed = 0;
while (bytes_marked < kBytesUntilInterruptCheck &&
while (current_marked_bytes < kBytesUntilInterruptCheck &&
objects_processed < kObjectsUntilInterrupCheck) {
HeapObject* object;
if (!shared_->Pop(task_id, &object)) {
......@@ -380,10 +380,12 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
bailout_->Push(task_id, object);
} else {
Map* map = object->synchronized_map();
bytes_marked += visitor.Visit(map, object);
current_marked_bytes += visitor.Visit(map, object);
}
}
total_bytes_marked += bytes_marked;
marked_bytes += current_marked_bytes;
base::AsAtomicWord::Relaxed_Store<size_t>(&task_state->marked_bytes,
marked_bytes);
if (task_state->interrupt_request.Value()) {
task_state->interrupt_condition.Wait(&task_state->lock);
}
......@@ -402,11 +404,13 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
--pending_task_count_;
pending_condition_.NotifyAll();
}
base::AsAtomicWord::Relaxed_Store<size_t>(&task_state->marked_bytes, 0);
total_marked_bytes_.Increment(marked_bytes);
}
if (FLAG_trace_concurrent_marking) {
heap_->isolate()->PrintWithTimestamp(
"Task %d concurrently marked %dKB in %.2fms\n", task_id,
static_cast<int>(total_bytes_marked / KB), time_ms);
static_cast<int>(marked_bytes / KB), time_ms);
}
}
......@@ -470,6 +474,7 @@ void ConcurrentMarking::FlushLiveBytes(
}
live_bytes.clear();
}
total_marked_bytes_.SetValue(0);
}
void ConcurrentMarking::ClearLiveness(MemoryChunk* chunk) {
......@@ -480,6 +485,16 @@ void ConcurrentMarking::ClearLiveness(MemoryChunk* chunk) {
}
}
size_t ConcurrentMarking::TotalMarkedBytes() {
size_t result = 0;
for (int i = 1; i <= task_count_; i++) {
result +=
base::AsAtomicWord::Relaxed_Load<size_t>(&task_state_[i].marked_bytes);
}
result += total_marked_bytes_.Value();
return result;
}
ConcurrentMarking::PauseScope::PauseScope(ConcurrentMarking* concurrent_marking)
: concurrent_marking_(concurrent_marking) {
if (!FLAG_concurrent_marking) return;
......
......@@ -53,6 +53,8 @@ class ConcurrentMarking {
int TaskCount() { return task_count_; }
size_t TotalMarkedBytes();
private:
struct TaskState {
// When the concurrent marking task has this lock, then objects in the
......@@ -65,6 +67,7 @@ class ConcurrentMarking {
// flag is cleared by the main thread.
base::ConditionVariable interrupt_condition;
LiveBytesMap live_bytes;
size_t marked_bytes;
char cache_line_padding[64];
};
class Task;
......@@ -74,6 +77,7 @@ class ConcurrentMarking {
MarkingWorklist* bailout_;
WeakObjects* weak_objects_;
TaskState task_state_[kMaxTasks + 1];
base::AtomicNumber<size_t> total_marked_bytes_;
base::Mutex pending_lock_;
base::ConditionVariable pending_condition_;
int pending_task_count_;
......
......@@ -1176,9 +1176,14 @@ size_t IncrementalMarking::Step(size_t bytes_to_process,
heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed);
if (FLAG_trace_incremental_marking) {
heap_->isolate()->PrintWithTimestamp(
"[IncrementalMarking] Step %s %zu bytes (%zu) in %.1f\n",
step_origin == StepOrigin::kV8 ? "in v8" : "in task", bytes_processed,
bytes_to_process, duration);
"[IncrementalMarking] Step %s %" PRIuS "KB (%" PRIuS "KB) in %.1f\n",
step_origin == StepOrigin::kV8 ? "in v8" : "in task",
bytes_processed / KB, bytes_to_process / KB, duration);
}
if (FLAG_trace_concurrent_marking) {
heap_->isolate()->PrintWithTimestamp(
"Concurrently marked %" PRIuS "KB\n",
heap_->concurrent_marking()->TotalMarkedBytes() / KB);
}
return bytes_processed;
}
......
......@@ -62,6 +62,20 @@ TEST(ConcurrentMarkingReschedule) {
delete concurrent_marking;
}
TEST(ConcurrentMarkingMarkedBytes) {
if (!i::FLAG_concurrent_marking) return;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = CcTest::heap();
HandleScope sc(isolate);
Handle<FixedArray> root = isolate->factory()->NewFixedArray(1000000);
CcTest::CollectAllGarbage();
if (!heap->incremental_marking()->IsStopped()) return;
heap::SimulateIncrementalMarking(heap, false);
heap->concurrent_marking()->EnsureCompleted();
CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
}
} // namespace heap
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment