array-buffer-sweeper.h 3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// Copyright 2020 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_ARRAY_BUFFER_SWEEPER_H_
#define V8_HEAP_ARRAY_BUFFER_SWEEPER_H_

#include "src/base/platform/mutex.h"
#include "src/objects/js-array-buffer.h"
#include "src/tasks/cancelable-task.h"

namespace v8 {
namespace internal {

class ArrayBufferExtension;
class Heap;

// Singly linked-list of ArrayBufferExtensions that stores head and tail of the
// list to allow for concatenation of lists.
struct ArrayBufferList {
21
  ArrayBufferList() : head_(nullptr), tail_(nullptr), bytes_(0) {}
22 23 24

  ArrayBufferExtension* head_;
  ArrayBufferExtension* tail_;
25
  size_t bytes_;
26 27 28 29 30 31

  bool IsEmpty() {
    DCHECK_IMPLIES(head_, tail_);
    return head_ == nullptr;
  }

32 33 34 35 36 37 38
  size_t Bytes() { return bytes_; }
  size_t BytesSlow();

  void Reset() {
    head_ = tail_ = nullptr;
    bytes_ = 0;
  }
39 40 41 42 43 44 45 46 47 48 49 50

  void Append(ArrayBufferExtension* extension);
  void Append(ArrayBufferList* list);

  V8_EXPORT_PRIVATE bool Contains(ArrayBufferExtension* extension);
};

// The ArrayBufferSweeper iterates and deletes ArrayBufferExtensions
// concurrently to the application.
class ArrayBufferSweeper {
 public:
  explicit ArrayBufferSweeper(Heap* heap)
51 52
      : heap_(heap),
        sweeping_in_progress_(false),
53
        freed_bytes_(0),
54 55
        young_bytes_(0),
        old_bytes_(0) {}
56 57 58 59 60 61 62 63 64 65 66
  ~ArrayBufferSweeper() { ReleaseAll(); }

  void EnsureFinished();
  void RequestSweepYoung();
  void RequestSweepFull();

  void Append(JSArrayBuffer object, ArrayBufferExtension* extension);

  ArrayBufferList young() { return young_; }
  ArrayBufferList old() { return old_; }

67 68 69
  size_t YoungBytes();
  size_t OldBytes();

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
 private:
  enum class SweepingScope { Young, Full };

  enum class SweepingState { Uninitialized, Prepared, Swept };

  struct SweepingJob {
    CancelableTaskManager::Id id;
    SweepingState state;
    ArrayBufferList young;
    ArrayBufferList old;
    SweepingScope scope;

    SweepingJob();

    static SweepingJob Prepare(ArrayBufferList young, ArrayBufferList old,
                               SweepingScope scope);
  } job_;

  void Merge();

90 91
  void DecrementExternalMemoryCounters();
  void IncrementExternalMemoryCounters(size_t bytes);
92
  void IncrementFreedBytes(size_t bytes);
93

94 95 96
  void RequestSweep(SweepingScope sweeping_task);
  void Prepare(SweepingScope sweeping_task);

97 98 99
  void Sweep();
  void SweepYoung();
  void SweepFull();
100
  ArrayBufferList SweepListFull(ArrayBufferList* list);
101

102 103 104 105 106 107 108 109 110 111
  ArrayBufferList SweepYoungGen();
  void SweepOldGen(ArrayBufferExtension* extension);

  void ReleaseAll();
  void ReleaseAll(ArrayBufferList* extension);

  Heap* const heap_;
  bool sweeping_in_progress_;
  base::Mutex sweeping_mutex_;
  base::ConditionVariable job_finished_;
112
  std::atomic<size_t> freed_bytes_;
113 114 115

  ArrayBufferList young_;
  ArrayBufferList old_;
116 117 118

  size_t young_bytes_;
  size_t old_bytes_;
119 120 121 122 123 124
};

}  // namespace internal
}  // namespace v8

#endif  // V8_HEAP_ARRAY_BUFFER_SWEEPER_H_