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