gfx/skia/trunk/src/core/SkSmallAllocator.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2014 Google, Inc
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #ifndef SkSmallAllocator_DEFINED
     9 #define SkSmallAllocator_DEFINED
    11 #include "SkTDArray.h"
    12 #include "SkTypes.h"
    14 // Used by SkSmallAllocator to call the destructor for objects it has
    15 // allocated.
    16 template<typename T> void destroyT(void* ptr) {
    17    static_cast<T*>(ptr)->~T();
    18 }
    20 /*
    21  *  Template class for allocating small objects without additional heap memory
    22  *  allocations. kMaxObjects is a hard limit on the number of objects that can
    23  *  be allocated using this class. After that, attempts to create more objects
    24  *  with this class will assert and return NULL.
    25  *  kTotalBytes is the total number of bytes provided for storage for all
    26  *  objects created by this allocator. If an object to be created is larger
    27  *  than the storage (minus storage already used), it will be allocated on the
    28  *  heap. This class's destructor will handle calling the destructor for each
    29  *  object it allocated and freeing its memory.
    30  */
    31 template<uint32_t kMaxObjects, size_t kTotalBytes>
    32 class SkSmallAllocator : public SkNoncopyable {
    33 public:
    34     SkSmallAllocator()
    35     : fStorageUsed(0)
    36     , fNumObjects(0)
    37     {}
    39     ~SkSmallAllocator() {
    40         // Destruct in reverse order, in case an earlier object points to a
    41         // later object.
    42         while (fNumObjects > 0) {
    43             fNumObjects--;
    44             Rec* rec = &fRecs[fNumObjects];
    45             rec->fKillProc(rec->fObj);
    46             // Safe to do if fObj is in fStorage, since fHeapStorage will
    47             // point to NULL.
    48             sk_free(rec->fHeapStorage);
    49         }
    50     }
    52     /*
    53      *  Create a new object of type T. Its lifetime will be handled by this
    54      *  SkSmallAllocator.
    55      *  Each version behaves the same but takes a different number of
    56      *  arguments.
    57      *  Note: If kMaxObjects have been created by this SkSmallAllocator, NULL
    58      *  will be returned.
    59      */
    60     template<typename T>
    61     T* createT() {
    62         void* buf = this->reserveT<T>();
    63         if (NULL == buf) {
    64             return NULL;
    65         }
    66         SkNEW_PLACEMENT(buf, T);
    67         return static_cast<T*>(buf);
    68     }
    70     template<typename T, typename A1> T* createT(const A1& a1) {
    71         void* buf = this->reserveT<T>();
    72         if (NULL == buf) {
    73             return NULL;
    74         }
    75         SkNEW_PLACEMENT_ARGS(buf, T, (a1));
    76         return static_cast<T*>(buf);
    77     }
    79     template<typename T, typename A1, typename A2>
    80     T* createT(const A1& a1, const A2& a2) {
    81         void* buf = this->reserveT<T>();
    82         if (NULL == buf) {
    83             return NULL;
    84         }
    85         SkNEW_PLACEMENT_ARGS(buf, T, (a1, a2));
    86         return static_cast<T*>(buf);
    87     }
    89     template<typename T, typename A1, typename A2, typename A3>
    90     T* createT(const A1& a1, const A2& a2, const A3& a3) {
    91         void* buf = this->reserveT<T>();
    92         if (NULL == buf) {
    93             return NULL;
    94         }
    95         SkNEW_PLACEMENT_ARGS(buf, T, (a1, a2, a3));
    96         return static_cast<T*>(buf);
    97     }
    99     /*
   100      *  Reserve a specified amount of space (must be enough space for one T).
   101      *  The space will be in fStorage if there is room, or on the heap otherwise.
   102      *  Either way, this class will call ~T() in its destructor and free the heap
   103      *  allocation if necessary.
   104      *  Unlike createT(), this method will not call the constructor of T.
   105      */
   106     template<typename T> void* reserveT(size_t storageRequired = sizeof(T)) {
   107         SkASSERT(fNumObjects < kMaxObjects);
   108         SkASSERT(storageRequired >= sizeof(T));
   109         if (kMaxObjects == fNumObjects) {
   110             return NULL;
   111         }
   112         const size_t storageRemaining = SkAlign4(kTotalBytes) - fStorageUsed;
   113         storageRequired = SkAlign4(storageRequired);
   114         Rec* rec = &fRecs[fNumObjects];
   115         if (storageRequired > storageRemaining) {
   116             // Allocate on the heap. Ideally we want to avoid this situation,
   117             // but we're not sure we can catch all callers, so handle it but
   118             // assert false in debug mode.
   119             SkASSERT(false);
   120             rec->fHeapStorage = sk_malloc_throw(storageRequired);
   121             rec->fObj = static_cast<void*>(rec->fHeapStorage);
   122         } else {
   123             // There is space in fStorage.
   124             rec->fHeapStorage = NULL;
   125             SkASSERT(SkIsAlign4(fStorageUsed));
   126             rec->fObj = static_cast<void*>(fStorage + (fStorageUsed / 4));
   127             fStorageUsed += storageRequired;
   128         }
   129         rec->fKillProc = destroyT<T>;
   130         fNumObjects++;
   131         return rec->fObj;
   132     }
   134 private:
   135     struct Rec {
   136         void* fObj;
   137         void* fHeapStorage;
   138         void  (*fKillProc)(void*);
   139     };
   141     // Number of bytes used so far.
   142     size_t              fStorageUsed;
   143     // Pad the storage size to be 4-byte aligned.
   144     uint32_t            fStorage[SkAlign4(kTotalBytes) >> 2];
   145     uint32_t            fNumObjects;
   146     Rec                 fRecs[kMaxObjects];
   147 };
   149 #endif // SkSmallAllocator_DEFINED

mercurial