Home | History | Annotate | Download | only in platform
      1 /*
      2  * Copyright (C) 2011 Apple Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef PODFreeListArena_h
     27 #define PODFreeListArena_h
     28 
     29 #include "core/platform/PODArena.h"
     30 
     31 namespace WebCore {
     32 
     33 // FIXME: Disassociate PODFreeListArena from PODArena, crbug.com/266535
     34 template <class T>
     35 class PODFreeListArena : public PODArena {
     36 public:
     37     typedef Vector<OwnPtr<Chunk> > ChunkVector;
     38 
     39     static PassRefPtr<PODFreeListArena> create()
     40     {
     41         return adoptRef(new PODFreeListArena);
     42     }
     43 
     44     // Creates a new PODArena configured with the given Allocator.
     45     static PassRefPtr<PODFreeListArena> create(PassRefPtr<Allocator> allocator)
     46     {
     47         return adoptRef(new PODFreeListArena(allocator));
     48     }
     49 
     50     // Allocates an object from the arena.
     51     T* allocateObject()
     52     {
     53         size_t roundedSize = roundUp(sizeof(T), minAlignment<T>());
     54         void* ptr = allocate(roundedSize);
     55         if (ptr) {
     56             // Use placement operator new to allocate a T at this location.
     57             new(ptr) T();
     58         }
     59         return static_cast<T*>(ptr);
     60     }
     61 
     62     template<class Argument1Type> T* allocateObject(const Argument1Type& argument1)
     63     {
     64         size_t roundedSize = roundUp(sizeof(T), minAlignment<T>());
     65         void* ptr = allocate(roundedSize);
     66         if (ptr) {
     67             // Use placement operator new to allocate a T at this location.
     68             new(ptr) T(argument1);
     69         }
     70         return static_cast<T*>(ptr);
     71     }
     72 
     73     void freeObject(T* ptr)
     74     {
     75         FixedSizeMemoryChunk* oldFreeList = m_freeList;
     76 
     77         m_freeList = reinterpret_cast<FixedSizeMemoryChunk*>(ptr);
     78         m_freeList->next = oldFreeList;
     79     }
     80 
     81 private:
     82     PODFreeListArena()
     83         : PODArena(), m_freeList(0) { }
     84 
     85     explicit PODFreeListArena(PassRefPtr<Allocator> allocator)
     86         : PODArena(allocator), m_freeList(0) { }
     87 
     88     void* allocate(size_t size)
     89     {
     90         ASSERT(size == roundUp(sizeof(T), minAlignment<T>()));
     91 
     92         if (m_freeList) {
     93             void* memory = m_freeList;
     94             m_freeList = m_freeList->next;
     95             return memory;
     96         }
     97 
     98         void* memory = 0;
     99         if (m_current)
    100             memory = m_current->allocate(size);
    101 
    102         if (!memory) {
    103             m_chunks.append(adoptPtr(new Chunk(m_allocator.get(), m_currentChunkSize)));
    104             m_current = m_chunks.last().get();
    105             memory = m_current->allocate(size);
    106         }
    107         return memory;
    108     }
    109 
    110     int getFreeListSizeForTesting() const
    111     {
    112         int total = 0;
    113         for (FixedSizeMemoryChunk* cur = m_freeList; cur; cur = cur->next) {
    114             total++;
    115         }
    116         return total;
    117     }
    118 
    119     // This free list contains pointers within every chunk that's been allocated so
    120     // far. None of the individual chunks can be freed until the arena is
    121     // destroyed.
    122     struct FixedSizeMemoryChunk {
    123         FixedSizeMemoryChunk* next;
    124     };
    125     FixedSizeMemoryChunk* m_freeList;
    126 
    127     friend class PODFreeListArenaTest;
    128 };
    129 
    130 } // namespace WebCore
    131 
    132 #endif
    133