Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2003 Apple Computer, Inc.
      3  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
      4  *
      5  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Lesser General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2.1 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Lesser General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, write to the Free Software
     19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     20  *
     21  * Alternatively, the contents of this file may be used under the terms
     22  * of either the Mozilla Public License Version 1.1, found at
     23  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
     24  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
     25  * (the "GPL"), in which case the provisions of the MPL or the GPL are
     26  * applicable instead of those above.  If you wish to allow use of your
     27  * version of this file only under the terms of one of those two
     28  * licenses (the MPL or the GPL) and not to allow others to use your
     29  * version of this file under the LGPL, indicate your decision by
     30  * deletingthe provisions above and replace them with the notice and
     31  * other provisions required by the MPL or the GPL, as the case may be.
     32  * If you do not delete the provisions above, a recipient may use your
     33  * version of this file under any of the LGPL, the MPL or the GPL.
     34  */
     35 
     36 #include "config.h"
     37 #include "RenderArena.h"
     38 
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #include <wtf/Assertions.h>
     42 
     43 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
     44 
     45 namespace WebCore {
     46 
     47 #ifndef NDEBUG
     48 
     49 const int signature = 0xDBA00AEA;
     50 const int signatureDead = 0xDBA00AED;
     51 
     52 typedef struct {
     53     RenderArena* arena;
     54     size_t size;
     55     int signature;
     56 } RenderArenaDebugHeader;
     57 
     58 static const size_t debugHeaderSize = ARENA_ALIGN(sizeof(RenderArenaDebugHeader));
     59 
     60 #endif
     61 
     62 RenderArena::RenderArena(unsigned arenaSize)
     63 {
     64     // Initialize the arena pool
     65     INIT_ARENA_POOL(&m_pool, "RenderArena", arenaSize);
     66 
     67     // Zero out the recyclers array
     68     memset(m_recyclers, 0, sizeof(m_recyclers));
     69 }
     70 
     71 RenderArena::~RenderArena()
     72 {
     73     FinishArenaPool(&m_pool);
     74 }
     75 
     76 void* RenderArena::allocate(size_t size)
     77 {
     78 #ifndef NDEBUG
     79     // Use standard malloc so that memory debugging tools work.
     80     ASSERT(this);
     81     void* block = ::malloc(debugHeaderSize + size);
     82     RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block);
     83     header->arena = this;
     84     header->size = size;
     85     header->signature = signature;
     86     return static_cast<char*>(block) + debugHeaderSize;
     87 #else
     88     void* result = 0;
     89 
     90     // Ensure we have correct alignment for pointers.  Important for Tru64
     91     size = ROUNDUP(size, sizeof(void*));
     92 
     93     // Check recyclers first
     94     if (size < gMaxRecycledSize) {
     95         const int index = size >> 2;
     96 
     97         result = m_recyclers[index];
     98         if (result) {
     99             // Need to move to the next object
    100             void* next = *((void**)result);
    101             m_recyclers[index] = next;
    102         }
    103     }
    104 
    105     if (!result) {
    106         // Allocate a new chunk from the arena
    107         ARENA_ALLOCATE(result, &m_pool, size);
    108     }
    109 
    110     return result;
    111 #endif
    112 }
    113 
    114 void RenderArena::free(size_t size, void* ptr)
    115 {
    116 #ifndef NDEBUG
    117     // Use standard free so that memory debugging tools work.
    118     void* block = static_cast<char*>(ptr) - debugHeaderSize;
    119     RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block);
    120     ASSERT(header->signature == signature);
    121     ASSERT_UNUSED(size, header->size == size);
    122     ASSERT(header->arena == this);
    123     header->signature = signatureDead;
    124     ::free(block);
    125 #else
    126     // Ensure we have correct alignment for pointers.  Important for Tru64
    127     size = ROUNDUP(size, sizeof(void*));
    128 
    129     // See if it's a size that we recycle
    130     if (size < gMaxRecycledSize) {
    131         const int index = size >> 2;
    132         void* currentTop = m_recyclers[index];
    133         m_recyclers[index] = ptr;
    134         *((void**)ptr) = currentTop;
    135     }
    136 #endif
    137 }
    138 
    139 #ifdef ANDROID_INSTRUMENT
    140 size_t RenderArena::reportPoolSize() const
    141 {
    142     return ReportPoolSize(&m_pool);
    143 }
    144 #endif
    145 
    146 } // namespace WebCore
    147