1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/heap/sweeper-thread.h"
6
7#include "src/v8.h"
8
9#include "src/isolate.h"
10#include "src/v8threads.h"
11
12namespace v8 {
13namespace internal {
14
15static const int kSweeperThreadStackSize = 64 * KB;
16
17SweeperThread::SweeperThread(Isolate* isolate)
18    : Thread(Thread::Options("v8:SweeperThread", kSweeperThreadStackSize)),
19      isolate_(isolate),
20      heap_(isolate->heap()),
21      collector_(heap_->mark_compact_collector()),
22      start_sweeping_semaphore_(0),
23      end_sweeping_semaphore_(0),
24      stop_semaphore_(0) {
25  DCHECK(!FLAG_job_based_sweeping);
26  base::NoBarrier_Store(&stop_thread_, static_cast<base::AtomicWord>(false));
27}
28
29
30void SweeperThread::Run() {
31  Isolate::SetIsolateThreadLocals(isolate_, NULL);
32  DisallowHeapAllocation no_allocation;
33  DisallowHandleAllocation no_handles;
34  DisallowHandleDereference no_deref;
35
36  while (true) {
37    start_sweeping_semaphore_.Wait();
38
39    if (base::Acquire_Load(&stop_thread_)) {
40      stop_semaphore_.Signal();
41      return;
42    }
43
44    collector_->SweepInParallel(heap_->old_data_space(), 0);
45    collector_->SweepInParallel(heap_->old_pointer_space(), 0);
46    end_sweeping_semaphore_.Signal();
47  }
48}
49
50
51void SweeperThread::Stop() {
52  base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(true));
53  start_sweeping_semaphore_.Signal();
54  stop_semaphore_.Wait();
55  Join();
56}
57
58
59void SweeperThread::StartSweeping() { start_sweeping_semaphore_.Signal(); }
60
61
62void SweeperThread::WaitForSweeperThread() { end_sweeping_semaphore_.Wait(); }
63
64
65bool SweeperThread::SweepingCompleted() {
66  bool value = end_sweeping_semaphore_.WaitFor(base::TimeDelta::FromSeconds(0));
67  if (value) {
68    end_sweeping_semaphore_.Signal();
69  }
70  return value;
71}
72
73
74int SweeperThread::NumberOfThreads(int max_available) {
75  if (!FLAG_concurrent_sweeping && !FLAG_parallel_sweeping) return 0;
76  if (FLAG_sweeper_threads > 0) return FLAG_sweeper_threads;
77  if (FLAG_concurrent_sweeping) return max_available - 1;
78  DCHECK(FLAG_parallel_sweeping);
79  return max_available;
80}
81}
82}  // namespace v8::internal
83