• 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 <memory>
9 
10 #include "src/base/logging.h"
11 #include "src/base/platform/mutex.h"
12 #include "src/objects/js-array-buffer.h"
13 #include "src/tasks/cancelable-task.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 class ArrayBufferExtension;
19 class Heap;
20 
21 // Singly linked-list of ArrayBufferExtensions that stores head and tail of the
22 // list to allow for concatenation of lists.
23 struct ArrayBufferList final {
24   bool IsEmpty() const;
ApproximateBytesfinal25   size_t ApproximateBytes() const { return bytes_; }
26   size_t BytesSlow() const;
27 
28   void Append(ArrayBufferExtension* extension);
29   void Append(ArrayBufferList* list);
30 
31   V8_EXPORT_PRIVATE bool ContainsSlow(ArrayBufferExtension* extension) const;
32 
33  private:
34   ArrayBufferExtension* head_ = nullptr;
35   ArrayBufferExtension* tail_ = nullptr;
36   // Bytes are approximate as they may be subtracted eagerly, while the
37   // `ArrayBufferExtension` is still in the list. The extension will only be
38   // dropped on next sweep.
39   size_t bytes_ = 0;
40 
41   friend class ArrayBufferSweeper;
42 };
43 
44 // The ArrayBufferSweeper iterates and deletes ArrayBufferExtensions
45 // concurrently to the application.
46 class ArrayBufferSweeper final {
47  public:
48   enum class SweepingType { kYoung, kFull };
49 
50   explicit ArrayBufferSweeper(Heap* heap);
51   ~ArrayBufferSweeper();
52 
53   void RequestSweep(SweepingType sweeping_type);
54   void EnsureFinished();
55 
56   // Track the given ArrayBufferExtension for the given JSArrayBuffer.
57   void Append(JSArrayBuffer object, ArrayBufferExtension* extension);
58 
59   // Detaches an ArrayBufferExtension from a JSArrayBuffer.
60   void Detach(JSArrayBuffer object, ArrayBufferExtension* extension);
61 
young()62   const ArrayBufferList& young() const { return young_; }
old()63   const ArrayBufferList& old() const { return old_; }
64 
65   // Bytes accounted in the young generation. Rebuilt during sweeping.
YoungBytes()66   size_t YoungBytes() const { return young().ApproximateBytes(); }
67   // Bytes accounted in the old generation. Rebuilt during sweeping.
OldBytes()68   size_t OldBytes() const { return old().ApproximateBytes(); }
69 
70  private:
71   struct SweepingJob;
72 
73   enum class SweepingState { kInProgress, kDone };
74 
sweeping_in_progress()75   bool sweeping_in_progress() const { return job_.get(); }
76 
77   // Finishes sweeping if it is already done.
78   void FinishIfDone();
79 
80   // Increments external memory counters outside of ArrayBufferSweeper.
81   // Increment may trigger GC.
82   void IncrementExternalMemoryCounters(size_t bytes);
83   void DecrementExternalMemoryCounters(size_t bytes);
84 
85   void Prepare(SweepingType type);
86   void Finalize();
87 
88   void ReleaseAll(ArrayBufferList* extension);
89 
90   Heap* const heap_;
91   std::unique_ptr<SweepingJob> job_;
92   base::Mutex sweeping_mutex_;
93   base::ConditionVariable job_finished_;
94   ArrayBufferList young_;
95   ArrayBufferList old_;
96 };
97 
98 }  // namespace internal
99 }  // namespace v8
100 
101 #endif  // V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
102