• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #ifndef V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
6 #define V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
7 
8 #include "src/base/platform/mutex.h"
9 #include "src/objects/js-array-buffer.h"
10 #include "src/tasks/cancelable-task.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class ArrayBufferExtension;
16 class Heap;
17 
18 // Singly linked-list of ArrayBufferExtensions that stores head and tail of the
19 // list to allow for concatenation of lists.
20 struct ArrayBufferList {
ArrayBufferListArrayBufferList21   ArrayBufferList() : head_(nullptr), tail_(nullptr), bytes_(0) {}
22 
23   ArrayBufferExtension* head_;
24   ArrayBufferExtension* tail_;
25   size_t bytes_;
26 
IsEmptyArrayBufferList27   bool IsEmpty() {
28     DCHECK_IMPLIES(head_, tail_);
29     return head_ == nullptr;
30   }
31 
BytesArrayBufferList32   size_t Bytes() { return bytes_; }
33   size_t BytesSlow();
34 
ResetArrayBufferList35   void Reset() {
36     head_ = tail_ = nullptr;
37     bytes_ = 0;
38   }
39 
40   void Append(ArrayBufferExtension* extension);
41   void Append(ArrayBufferList* list);
42 
43   V8_EXPORT_PRIVATE bool Contains(ArrayBufferExtension* extension);
44 };
45 
46 // The ArrayBufferSweeper iterates and deletes ArrayBufferExtensions
47 // concurrently to the application.
48 class ArrayBufferSweeper {
49  public:
ArrayBufferSweeper(Heap * heap)50   explicit ArrayBufferSweeper(Heap* heap)
51       : heap_(heap),
52         sweeping_in_progress_(false),
53         freed_bytes_(0),
54         young_bytes_(0),
55         old_bytes_(0) {}
~ArrayBufferSweeper()56   ~ArrayBufferSweeper() { ReleaseAll(); }
57 
58   void EnsureFinished();
59   void RequestSweepYoung();
60   void RequestSweepFull();
61 
62   void Append(JSArrayBuffer object, ArrayBufferExtension* extension);
63 
young()64   ArrayBufferList young() { return young_; }
old()65   ArrayBufferList old() { return old_; }
66 
67   size_t YoungBytes();
68   size_t OldBytes();
69 
70  private:
71   enum class SweepingScope { kYoung, kFull };
72 
73   enum class SweepingState { kInProgress, kDone };
74 
75   struct SweepingJob {
76     ArrayBufferSweeper* sweeper_;
77     CancelableTaskManager::Id id_;
78     std::atomic<SweepingState> state_;
79     ArrayBufferList young_;
80     ArrayBufferList old_;
81     SweepingScope scope_;
82 
SweepingJobSweepingJob83     SweepingJob(ArrayBufferSweeper* sweeper, ArrayBufferList young,
84                 ArrayBufferList old, SweepingScope scope)
85         : sweeper_(sweeper),
86           id_(0),
87           state_(SweepingState::kInProgress),
88           young_(young),
89           old_(old),
90           scope_(scope) {}
91 
92     void Sweep();
93     void SweepYoung();
94     void SweepFull();
95     ArrayBufferList SweepListFull(ArrayBufferList* list);
96   };
97 
98   base::Optional<SweepingJob> job_;
99 
100   void Merge();
101   void AdjustCountersAndMergeIfPossible();
102 
103   void DecrementExternalMemoryCounters();
104   void IncrementExternalMemoryCounters(size_t bytes);
105   void IncrementFreedBytes(size_t bytes);
106   void IncrementFreedYoungBytes(size_t bytes);
107 
108   void RequestSweep(SweepingScope sweeping_task);
109   void Prepare(SweepingScope sweeping_task);
110 
111   ArrayBufferList SweepYoungGen();
112   void SweepOldGen(ArrayBufferExtension* extension);
113 
114   void ReleaseAll();
115   void ReleaseAll(ArrayBufferList* extension);
116 
117   Heap* const heap_;
118   bool sweeping_in_progress_;
119   base::Mutex sweeping_mutex_;
120   base::ConditionVariable job_finished_;
121   std::atomic<size_t> freed_bytes_;
122 
123   ArrayBufferList young_;
124   ArrayBufferList old_;
125 
126   size_t young_bytes_;
127   size_t old_bytes_;
128 };
129 
130 }  // namespace internal
131 }  // namespace v8
132 
133 #endif  // V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
134