123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef mozalloc_VolatileBuffer_h
- #define mozalloc_VolatileBuffer_h
- #include "mozilla/mozalloc.h"
- #include "mozilla/Mutex.h"
- #include "mozilla/RefPtr.h"
- #include "mozilla/MemoryReporting.h"
- #include "mozilla/RefCounted.h"
- /* VolatileBuffer
- *
- * This class represents a piece of memory that can potentially be reclaimed
- * by the OS when not in use. As long as there are one or more
- * VolatileBufferPtrs holding on to a VolatileBuffer, the memory will remain
- * available. However, when there are no VolatileBufferPtrs holding a
- * VolatileBuffer, the OS can purge the pages if it wants to. The OS can make
- * better decisions about what pages to purge than we can.
- *
- * VolatileBuffers may not always be volatile - if the allocation is too small,
- * or if the OS doesn't support the feature, or if the OS doesn't want to,
- * the buffer will be allocated on heap.
- *
- * VolatileBuffer allocations are fallible. They are intended for uses where
- * one may allocate large buffers for caching data. Init() must be called
- * exactly once.
- *
- * After getting a reference to VolatileBuffer using VolatileBufferPtr,
- * WasPurged() can be used to check if the OS purged any pages in the buffer.
- * The OS cannot purge a buffer immediately after a VolatileBuffer is
- * initialized. At least one VolatileBufferPtr must be created before the
- * buffer can be purged, so the first use of VolatileBufferPtr does not need
- * to check WasPurged().
- *
- * When a buffer is purged, some or all of the buffer is zeroed out. This
- * API cannot tell which parts of the buffer were lost.
- *
- * VolatileBuffer and VolatileBufferPtr are threadsafe.
- */
- namespace mozilla {
- class VolatileBuffer
- {
- friend class VolatileBufferPtr_base;
- public:
- MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VolatileBuffer)
- VolatileBuffer();
- /* aAlignment must be a multiple of the pointer size */
- bool Init(size_t aSize, size_t aAlignment = sizeof(void*));
- size_t HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
- size_t NonHeapSizeOfExcludingThis() const;
- bool OnHeap() const;
- protected:
- bool Lock(void** aBuf);
- void Unlock();
- private:
- ~VolatileBuffer();
- /**
- * Protects mLockCount, mFirstLock, and changes to the volatility of our
- * buffer. Other member variables are read-only except in Init() and the
- * destructor.
- */
- Mutex mMutex;
- void* mBuf;
- size_t mSize;
- int mLockCount;
- #if defined(XP_WIN)
- bool mHeap;
- bool mFirstLock;
- #endif
- };
- class VolatileBufferPtr_base {
- public:
- explicit VolatileBufferPtr_base(VolatileBuffer* vbuf)
- : mVBuf(vbuf)
- , mMapping(nullptr)
- , mPurged(false)
- {
- Lock();
- }
- ~VolatileBufferPtr_base() {
- Unlock();
- }
- bool WasBufferPurged() const {
- return mPurged;
- }
- protected:
- RefPtr<VolatileBuffer> mVBuf;
- void* mMapping;
- void Set(VolatileBuffer* vbuf) {
- Unlock();
- mVBuf = vbuf;
- Lock();
- }
- private:
- bool mPurged;
- void Lock() {
- if (mVBuf) {
- mPurged = !mVBuf->Lock(&mMapping);
- } else {
- mMapping = nullptr;
- mPurged = false;
- }
- }
- void Unlock() {
- if (mVBuf) {
- mVBuf->Unlock();
- }
- }
- };
- template <class T>
- class VolatileBufferPtr : public VolatileBufferPtr_base
- {
- public:
- explicit VolatileBufferPtr(VolatileBuffer* vbuf) : VolatileBufferPtr_base(vbuf) {}
- VolatileBufferPtr() : VolatileBufferPtr_base(nullptr) {}
- VolatileBufferPtr(VolatileBufferPtr&& aOther)
- : VolatileBufferPtr_base(aOther.mVBuf)
- {
- aOther.Set(nullptr);
- }
- operator T*() const {
- return (T*) mMapping;
- }
- VolatileBufferPtr& operator=(VolatileBuffer* aVBuf)
- {
- Set(aVBuf);
- return *this;
- }
- VolatileBufferPtr& operator=(VolatileBufferPtr&& aOther)
- {
- MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
- Set(aOther.mVBuf);
- aOther.Set(nullptr);
- return *this;
- }
- private:
- VolatileBufferPtr(VolatileBufferPtr const& vbufptr) = delete;
- };
- } // namespace mozilla
- #endif /* mozalloc_VolatileBuffer_h */
|