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
RenderArena(unsigned arenaSize)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
~RenderArena()68 RenderArena::~RenderArena()
69 {
70 FinishArenaPool(&m_pool);
71 }
72
allocate(size_t size)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
free(size_t size,void * ptr)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(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
reportPoolSize() const136 size_t RenderArena::reportPoolSize() const
137 {
138 return ReportPoolSize(&m_pool);
139 }
140 #endif
141
142 } // namespace WebCore
143