1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/memory/mozalloc/VolatileBuffer.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,121 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef mozalloc_VolatileBuffer_h 1.9 +#define mozalloc_VolatileBuffer_h 1.10 + 1.11 +#include "mozilla/mozalloc.h" 1.12 +#include "mozilla/RefPtr.h" 1.13 +#include "mozilla/MemoryReporting.h" 1.14 +#include "mozilla/NullPtr.h" 1.15 + 1.16 +/* VolatileBuffer 1.17 + * 1.18 + * This class represents a piece of memory that can potentially be reclaimed 1.19 + * by the OS when not in use. As long as there are one or more 1.20 + * VolatileBufferPtrs holding on to a VolatileBuffer, the memory will remain 1.21 + * available. However, when there are no VolatileBufferPtrs holding a 1.22 + * VolatileBuffer, the OS can purge the pages if it wants to. The OS can make 1.23 + * better decisions about what pages to purge than we can. 1.24 + * 1.25 + * VolatileBuffers may not always be volatile - if the allocation is too small, 1.26 + * or if the OS doesn't support the feature, or if the OS doesn't want to, 1.27 + * the buffer will be allocated on heap. 1.28 + * 1.29 + * VolatileBuffer allocations are fallible. They are intended for uses where 1.30 + * one may allocate large buffers for caching data. Init() must be called 1.31 + * exactly once. 1.32 + * 1.33 + * After getting a reference to VolatileBuffer using VolatileBufferPtr, 1.34 + * WasPurged() can be used to check if the OS purged any pages in the buffer. 1.35 + * The OS cannot purge a buffer immediately after a VolatileBuffer is 1.36 + * initialized. At least one VolatileBufferPtr must be created before the 1.37 + * buffer can be purged, so the first use of VolatileBufferPtr does not need 1.38 + * to check WasPurged(). 1.39 + * 1.40 + * When a buffer is purged, some or all of the buffer is zeroed out. This 1.41 + * API cannot tell which parts of the buffer were lost. 1.42 + * 1.43 + * VolatileBuffer is not thread safe. Do not use VolatileBufferPtrs on 1.44 + * different threads. 1.45 + */ 1.46 + 1.47 +namespace mozilla { 1.48 + 1.49 +class MOZALLOC_EXPORT VolatileBuffer : public RefCounted<VolatileBuffer> 1.50 +{ 1.51 + friend class VolatileBufferPtr_base; 1.52 +public: 1.53 + MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer) 1.54 + VolatileBuffer(); 1.55 + ~VolatileBuffer(); 1.56 + 1.57 + /* aAlignment must be a multiple of the pointer size */ 1.58 + bool Init(size_t aSize, size_t aAlignment = sizeof(void*)); 1.59 + 1.60 + size_t HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; 1.61 + size_t NonHeapSizeOfExcludingThis() const; 1.62 + bool OnHeap() const; 1.63 + 1.64 +protected: 1.65 + bool Lock(void** aBuf); 1.66 + void Unlock(); 1.67 + 1.68 +private: 1.69 + void* mBuf; 1.70 + size_t mSize; 1.71 + int mLockCount; 1.72 +#if defined(ANDROID) 1.73 + int mFd; 1.74 +#elif defined(XP_DARWIN) 1.75 + bool mHeap; 1.76 +#elif defined(XP_WIN) 1.77 + bool mHeap; 1.78 + bool mFirstLock; 1.79 +#endif 1.80 +}; 1.81 + 1.82 +class VolatileBufferPtr_base { 1.83 +public: 1.84 + VolatileBufferPtr_base(VolatileBuffer* vbuf) : mVBuf(vbuf) { 1.85 + if (vbuf) { 1.86 + mPurged = !vbuf->Lock(&mMapping); 1.87 + } else { 1.88 + mMapping = nullptr; 1.89 + mPurged = false; 1.90 + } 1.91 + } 1.92 + 1.93 + ~VolatileBufferPtr_base() { 1.94 + if (mVBuf) { 1.95 + mVBuf->Unlock(); 1.96 + } 1.97 + } 1.98 + 1.99 + bool WasBufferPurged() const { 1.100 + return mPurged; 1.101 + } 1.102 + 1.103 +protected: 1.104 + void* mMapping; 1.105 + 1.106 +private: 1.107 + RefPtr<VolatileBuffer> mVBuf; 1.108 + bool mPurged; 1.109 +}; 1.110 + 1.111 +template <class T> 1.112 +class VolatileBufferPtr : public VolatileBufferPtr_base 1.113 +{ 1.114 +public: 1.115 + VolatileBufferPtr(VolatileBuffer* vbuf) : VolatileBufferPtr_base(vbuf) {} 1.116 + 1.117 + operator T*() const { 1.118 + return (T*) mMapping; 1.119 + } 1.120 +}; 1.121 + 1.122 +}; /* namespace mozilla */ 1.123 + 1.124 +#endif /* mozalloc_VolatileBuffer_h */