Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/VolatileBuffer.h
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#ifndef mozalloc_VolatileBuffer_h
6
#define mozalloc_VolatileBuffer_h
7
8
#include "mozilla/mozalloc.h"
9
#include "mozilla/Mutex.h"
10
#include "mozilla/RefPtr.h"
11
#include "mozilla/MemoryReporting.h"
12
#include "mozilla/RefCounted.h"
13
14
/* VolatileBuffer
15
 *
16
 * This class represents a piece of memory that can potentially be reclaimed
17
 * by the OS when not in use. As long as there are one or more
18
 * VolatileBufferPtrs holding on to a VolatileBuffer, the memory will remain
19
 * available. However, when there are no VolatileBufferPtrs holding a
20
 * VolatileBuffer, the OS can purge the pages if it wants to. The OS can make
21
 * better decisions about what pages to purge than we can.
22
 *
23
 * VolatileBuffers may not always be volatile - if the allocation is too small,
24
 * or if the OS doesn't support the feature, or if the OS doesn't want to,
25
 * the buffer will be allocated on heap.
26
 *
27
 * VolatileBuffer allocations are fallible. They are intended for uses where
28
 * one may allocate large buffers for caching data. Init() must be called
29
 * exactly once.
30
 *
31
 * After getting a reference to VolatileBuffer using VolatileBufferPtr,
32
 * WasPurged() can be used to check if the OS purged any pages in the buffer.
33
 * The OS cannot purge a buffer immediately after a VolatileBuffer is
34
 * initialized. At least one VolatileBufferPtr must be created before the
35
 * buffer can be purged, so the first use of VolatileBufferPtr does not need
36
 * to check WasPurged().
37
 *
38
 * When a buffer is purged, some or all of the buffer is zeroed out. This
39
 * API cannot tell which parts of the buffer were lost.
40
 *
41
 * VolatileBuffer and VolatileBufferPtr are threadsafe.
42
 */
43
44
namespace mozilla {
45
46
class VolatileBuffer
47
{
48
  friend class VolatileBufferPtr_base;
49
public:
50
  MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
51
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VolatileBuffer)
52
53
  VolatileBuffer();
54
55
  /* aAlignment must be a multiple of the pointer size */
56
  bool Init(size_t aSize, size_t aAlignment = sizeof(void*));
57
58
  size_t HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
59
  size_t NonHeapSizeOfExcludingThis() const;
60
  bool OnHeap() const;
61
62
protected:
63
  bool Lock(void** aBuf);
64
  void Unlock();
65
66
private:
67
  ~VolatileBuffer();
68
69
  /**
70
   * Protects mLockCount, mFirstLock, and changes to the volatility of our
71
   * buffer.  Other member variables are read-only except in Init() and the
72
   * destructor.
73
   */
74
  Mutex mMutex;
75
76
  void* mBuf;
77
  size_t mSize;
78
  int mLockCount;
79
#if defined(ANDROID)
80
  int mFd;
81
#elif defined(XP_DARWIN)
82
  bool mHeap;
83
#elif defined(XP_WIN)
84
  bool mHeap;
85
  bool mFirstLock;
86
#endif
87
};
88
89
class VolatileBufferPtr_base {
90
public:
91
  explicit VolatileBufferPtr_base(VolatileBuffer* vbuf)
92
    : mVBuf(vbuf)
93
    , mMapping(nullptr)
94
    , mPurged(false)
95
0
  {
96
0
    Lock();
97
0
  }
98
99
0
  ~VolatileBufferPtr_base() {
100
0
    Unlock();
101
0
  }
102
103
0
  bool WasBufferPurged() const {
104
0
    return mPurged;
105
0
  }
106
107
protected:
108
  RefPtr<VolatileBuffer> mVBuf;
109
  void* mMapping;
110
111
0
  void Set(VolatileBuffer* vbuf) {
112
0
    Unlock();
113
0
    mVBuf = vbuf;
114
0
    Lock();
115
0
  }
116
117
private:
118
  bool mPurged;
119
120
0
  void Lock() {
121
0
    if (mVBuf) {
122
0
      mPurged = !mVBuf->Lock(&mMapping);
123
0
    } else {
124
0
      mMapping = nullptr;
125
0
      mPurged = false;
126
0
    }
127
0
  }
128
129
0
  void Unlock() {
130
0
    if (mVBuf) {
131
0
      mVBuf->Unlock();
132
0
    }
133
0
  }
134
};
135
136
template <class T>
137
class VolatileBufferPtr : public VolatileBufferPtr_base
138
{
139
public:
140
0
  explicit VolatileBufferPtr(VolatileBuffer* vbuf) : VolatileBufferPtr_base(vbuf) {}
141
0
  VolatileBufferPtr() : VolatileBufferPtr_base(nullptr) {}
142
143
  VolatileBufferPtr(VolatileBufferPtr&& aOther)
144
    : VolatileBufferPtr_base(aOther.mVBuf)
145
  {
146
    aOther.Set(nullptr);
147
  }
148
149
0
  operator T*() const {
150
0
    return (T*) mMapping;
151
0
  }
Unexecuted instantiation: mozilla::VolatileBufferPtr<unsigned char>::operator unsigned char*() const
Unexecuted instantiation: mozilla::VolatileBufferPtr<char>::operator char*() const
152
153
  VolatileBufferPtr& operator=(VolatileBuffer* aVBuf)
154
0
  {
155
0
    Set(aVBuf);
156
0
    return *this;
157
0
  }
158
159
  VolatileBufferPtr& operator=(VolatileBufferPtr&& aOther)
160
  {
161
    MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
162
    Set(aOther.mVBuf);
163
    aOther.Set(nullptr);
164
    return *this;
165
  }
166
167
private:
168
  VolatileBufferPtr(VolatileBufferPtr const& vbufptr) = delete;
169
};
170
171
} // namespace mozilla
172
173
#endif /* mozalloc_VolatileBuffer_h */