00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef Arena_h
00041 #define Arena_h
00042
00043 #define ARENA_ALIGN_MASK 3
00044
00045 namespace WebCore {
00046
00047 typedef unsigned long uword;
00048
00049 struct Arena {
00050 Arena* next;
00051 uword base;
00052 uword limit;
00053 uword avail;
00054 };
00055
00056 struct ArenaPool {
00057 Arena first;
00058 Arena* current;
00059 unsigned int arenasize;
00060 uword mask;
00061 };
00062
00063 void InitArenaPool(ArenaPool *pool, const char *name,
00064 unsigned int size, unsigned int align);
00065 void FinishArenaPool(ArenaPool *pool);
00066 void FreeArenaPool(ArenaPool *pool);
00067 void* ArenaAllocate(ArenaPool *pool, unsigned int nb);
00068
00069 #define ARENA_ALIGN(pool, n) (((uword)(n) + ARENA_ALIGN_MASK) & ~ARENA_ALIGN_MASK)
00070 #define INIT_ARENA_POOL(pool, name, size) \
00071 InitArenaPool(pool, name, size, ARENA_ALIGN_MASK + 1)
00072
00073 #define ARENA_ALLOCATE(p, pool, nb) \
00074 Arena *_a = (pool)->current; \
00075 unsigned int _nb = ARENA_ALIGN(pool, nb); \
00076 uword _p = _a->avail; \
00077 uword _q = _p + _nb; \
00078 if (_q > _a->limit) \
00079 _p = (uword)ArenaAllocate(pool, _nb); \
00080 else \
00081 _a->avail = _q; \
00082 p = (void *)_p;
00083
00084 #define ARENA_GROW(p, pool, size, incr) \
00085 Arena *_a = (pool)->current; \
00086 unsigned int _incr = ARENA_ALIGN(pool, incr); \
00087 uword _p = _a->avail; \
00088 uword _q = _p + _incr; \
00089 if (_p == (uword)(p) + ARENA_ALIGN(pool, size) && \
00090 _q <= _a->limit) { \
00091 _a->avail = _q; \
00092 } else { \
00093 p = ArenaGrow(pool, p, size, incr); \
00094 }
00095
00096 #define ARENA_MARK(pool) ((void *) (pool)->current->avail)
00097 #define UPTRDIFF(p,q) ((uword)(p) - (uword)(q))
00098
00099 #ifdef DEBUG
00100 #define FREE_PATTERN 0xDA
00101 #define CLEAR_UNUSED(a) (ASSERT((a)->avail <= (a)->limit), \
00102 memset((void*)(a)->avail, FREE_PATTERN, \
00103 (a)->limit - (a)->avail))
00104 #define CLEAR_ARENA(a) memset((void*)(a), FREE_PATTERN, \
00105 (a)->limit - (uword)(a))
00106 #else
00107 #define CLEAR_UNUSED(a)
00108 #define CLEAR_ARENA(a)
00109 #endif
00110
00111 #define ARENA_RELEASE(pool, mark) \
00112 char *_m = (char *)(mark); \
00113 Arena *_a = (pool)->current; \
00114 if (UPTRDIFF(_m, _a->base) <= UPTRDIFF(_a->avail, _a->base)) { \
00115 _a->avail = (uword)ARENA_ALIGN(pool, _m); \
00116 CLEAR_UNUSED(_a); \
00117 } else { \
00118 ArenaRelease(pool, _m); \
00119 }
00120
00121 #define ARENA_DESTROY(pool, a, pnext) \
00122 if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
00123 *(pnext) = (a)->next; \
00124 CLEAR_ARENA(a); \
00125 fastFree(a); \
00126 (a) = 0;
00127
00128 }
00129
00130 #endif