LCOV - code coverage report
Current view: top level - memory/volatile - VolatileBuffer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 28 33 84.8 %
Date: 2017-07-14 16:53:18 Functions: 9 12 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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         100 :   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          50 :   explicit VolatileBufferPtr_base(VolatileBuffer* vbuf)
      92          50 :     : mVBuf(vbuf)
      93             :     , mMapping(nullptr)
      94          50 :     , mPurged(false)
      95             :   {
      96          50 :     Lock();
      97          50 :   }
      98             : 
      99           0 :   ~VolatileBufferPtr_base() {
     100           0 :     Unlock();
     101           0 :   }
     102             : 
     103         285 :   bool WasBufferPurged() const {
     104         285 :     return mPurged;
     105             :   }
     106             : 
     107             : protected:
     108             :   RefPtr<VolatileBuffer> mVBuf;
     109             :   void* mMapping;
     110             : 
     111          50 :   void Set(VolatileBuffer* vbuf) {
     112          50 :     Unlock();
     113          50 :     mVBuf = vbuf;
     114          50 :     Lock();
     115          50 :   }
     116             : 
     117             : private:
     118             :   bool mPurged;
     119             : 
     120         100 :   void Lock() {
     121         100 :     if (mVBuf) {
     122          50 :       mPurged = !mVBuf->Lock(&mMapping);
     123             :     } else {
     124          50 :       mMapping = nullptr;
     125          50 :       mPurged = false;
     126             :     }
     127         100 :   }
     128             : 
     129          50 :   void Unlock() {
     130          50 :     if (mVBuf) {
     131           0 :       mVBuf->Unlock();
     132             :     }
     133          50 :   }
     134             : };
     135             : 
     136             : template <class T>
     137           0 : class VolatileBufferPtr : public VolatileBufferPtr_base
     138             : {
     139             : public:
     140             :   explicit VolatileBufferPtr(VolatileBuffer* vbuf) : VolatileBufferPtr_base(vbuf) {}
     141          50 :   VolatileBufferPtr() : VolatileBufferPtr_base(nullptr) {}
     142             : 
     143             :   VolatileBufferPtr(VolatileBufferPtr&& aOther)
     144             :     : VolatileBufferPtr_base(aOther.mVBuf)
     145             :   {
     146             :     aOther.Set(nullptr);
     147             :   }
     148             : 
     149         335 :   operator T*() const {
     150         335 :     return (T*) mMapping;
     151             :   }
     152             : 
     153          50 :   VolatileBufferPtr& operator=(VolatileBuffer* aVBuf)
     154             :   {
     155          50 :     Set(aVBuf);
     156          50 :     return *this;
     157             :   }
     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 */

Generated by: LCOV version 1.13