e1d1e6ba14e28e3630f9cf8f720d8f13d147c172
2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Memory manager for GLSL compiler. The general idea is to do all
29 * allocations out of a large pool then just free the pool when done
30 * compiling to avoid intricate malloc/free tracking and memory leaks.
37 #include "slang_mem.h"
41 #define ROUND_UP(B) ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )
44 /** If 1, use conventional malloc/free. Helpful for debugging */
45 #define USE_MALLOC_FREE 0
50 GLuint Size
, Used
, Count
, Largest
;
52 struct slang_mempool_
*Next
;
57 _slang_new_mempool(GLuint initialSize
)
59 slang_mempool
*pool
= (slang_mempool
*) _mesa_calloc(sizeof(slang_mempool
));
61 pool
->Data
= (char *) _mesa_calloc(initialSize
);
62 /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
67 pool
->Size
= initialSize
;
75 _slang_delete_mempool(slang_mempool
*pool
)
79 slang_mempool
*next
= pool
->Next
;
81 printf("DELETE MEMPOOL %u / %u count=%u largest=%u\n",
82 pool->Used, pool->Size, pool->Count, pool->Largest);
85 _mesa_free(pool
->Data
);
89 /*printf("TOTAL ALLOCATED: %u\n", total);*/
95 check_zero(const char *addr
, GLuint n
)
98 for (i
= 0; i
< n
; i
++) {
107 is_valid_address(const slang_mempool
*pool
, void *addr
)
110 if ((char *) addr
>= pool
->Data
&&
111 (char *) addr
< pool
->Data
+ pool
->Used
)
122 * Alloc 'bytes' from shader mempool.
125 _slang_alloc(GLuint bytes
)
128 return _mesa_calloc(bytes
);
131 GET_CURRENT_CONTEXT(ctx
);
132 pool
= (slang_mempool
*) ctx
->Shader
.MemPool
;
138 if (pool
->Used
+ bytes
<= pool
->Size
) {
140 void *addr
= (void *) (pool
->Data
+ pool
->Used
);
142 check_zero((char*) addr
, bytes
);
144 pool
->Used
+= ROUND_UP(bytes
);
145 pool
->Largest
= MAX2(pool
->Largest
, bytes
);
147 /*printf("alloc %u Used %u\n", bytes, pool->Used);*/
150 else if (pool
->Next
) {
156 const GLuint sz
= MAX2(bytes
, pool
->Size
);
157 pool
->Next
= _slang_new_mempool(sz
);
159 /* we're _really_ out of memory */
164 pool
->Largest
= bytes
;
166 pool
->Used
= ROUND_UP(bytes
);
168 check_zero((char*) pool
->Data
, bytes
);
170 return (void *) pool
->Data
;
180 _slang_realloc(void *oldBuffer
, GLuint oldSize
, GLuint newSize
)
183 return _mesa_realloc(oldBuffer
, oldSize
, newSize
);
185 GET_CURRENT_CONTEXT(ctx
);
186 slang_mempool
*pool
= (slang_mempool
*) ctx
->Shader
.MemPool
;
188 if (newSize
< oldSize
) {
192 const GLuint copySize
= (oldSize
< newSize
) ? oldSize
: newSize
;
193 void *newBuffer
= _slang_alloc(newSize
);
196 ASSERT(is_valid_address(pool
, oldBuffer
));
198 if (newBuffer
&& oldBuffer
&& copySize
> 0)
199 _mesa_memcpy(newBuffer
, oldBuffer
, copySize
);
208 * Clone string, storing in current mempool.
211 _slang_strdup(const char *s
)
214 size_t l
= _mesa_strlen(s
);
215 char *s2
= (char *) _slang_alloc(l
+ 1);
227 * Don't actually free memory, but mark it (for debugging).
230 _slang_free(void *addr
)
236 GET_CURRENT_CONTEXT(ctx
);
237 slang_mempool
*pool
= (slang_mempool
*) ctx
->Shader
.MemPool
;
238 ASSERT(is_valid_address(pool
, addr
));