PageRenderTime 35ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jsarena.h

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C++ Header | 318 lines | 185 code | 47 blank | 86 comment | 18 complexity | 91c647bcc2878fbbba1fcfda277f2c8e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. *
  3. * ***** BEGIN LICENSE BLOCK *****
  4. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5. *
  6. * The contents of this file are subject to the Mozilla Public License Version
  7. * 1.1 (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. * http://www.mozilla.org/MPL/
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. *
  16. * The Original Code is Mozilla Communicator client code, released
  17. * March 31, 1998.
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Netscape Communications Corporation.
  21. * Portions created by the Initial Developer are Copyright (C) 1998
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. *
  26. * Alternatively, the contents of this file may be used under the terms of
  27. * either of the GNU General Public License Version 2 or later (the "GPL"),
  28. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29. * in which case the provisions of the GPL or the LGPL are applicable instead
  30. * of those above. If you wish to allow use of your version of this file only
  31. * under the terms of either the GPL or the LGPL, and not to allow others to
  32. * use your version of this file under the terms of the MPL, indicate your
  33. * decision by deleting the provisions above and replace them with the notice
  34. * and other provisions required by the GPL or the LGPL. If you do not delete
  35. * the provisions above, a recipient may use your version of this file under
  36. * the terms of any one of the MPL, the GPL or the LGPL.
  37. *
  38. * ***** END LICENSE BLOCK ***** */
  39. #ifndef jsarena_h___
  40. #define jsarena_h___
  41. /*
  42. * Lifetime-based fast allocation, inspired by much prior art, including
  43. * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
  44. * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
  45. *
  46. * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE).
  47. */
  48. #include <stdlib.h>
  49. #include "jstypes.h"
  50. #include "jscompat.h"
  51. JS_BEGIN_EXTERN_C
  52. typedef struct JSArena JSArena;
  53. typedef struct JSArenaPool JSArenaPool;
  54. struct JSArena {
  55. JSArena *next; /* next arena for this lifetime */
  56. jsuword base; /* aligned base address, follows this header */
  57. jsuword limit; /* one beyond last byte in arena */
  58. jsuword avail; /* points to next available byte */
  59. };
  60. #ifdef JS_ARENAMETER
  61. typedef struct JSArenaStats JSArenaStats;
  62. struct JSArenaStats {
  63. JSArenaStats *next; /* next in arenaStats list */
  64. char *name; /* name for debugging */
  65. uint32 narenas; /* number of arenas in pool */
  66. uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */
  67. uint32 nmallocs; /* number of malloc() calls */
  68. uint32 ndeallocs; /* number of lifetime deallocations */
  69. uint32 ngrows; /* number of JS_ARENA_GROW() calls */
  70. uint32 ninplace; /* number of in-place growths */
  71. uint32 nreallocs; /* number of arena grow extending reallocs */
  72. uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */
  73. uint32 nfastrels; /* number of "fast path" releases */
  74. size_t nbytes; /* total bytes allocated */
  75. size_t maxalloc; /* maximum allocation size in bytes */
  76. double variance; /* size variance accumulator */
  77. };
  78. #endif
  79. struct JSArenaPool {
  80. JSArena first; /* first arena in pool list */
  81. JSArena *current; /* arena from which to allocate space */
  82. size_t arenasize; /* net exact size of a new arena */
  83. jsuword mask; /* alignment mask (power-of-2 - 1) */
  84. size_t *quotap; /* pointer to the quota on pool allocation
  85. size or null if pool is unlimited */
  86. #ifdef JS_ARENAMETER
  87. JSArenaStats stats;
  88. #endif
  89. };
  90. #ifdef JS_ARENAMETER
  91. #define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap) \
  92. JS_InitArenaPool(pool, name, size, align, quotap)
  93. #else
  94. #define JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap) \
  95. JS_InitArenaPool(pool, size, align, quotap)
  96. #endif
  97. /*
  98. * If the including .c file uses only one power-of-2 alignment, it may define
  99. * JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
  100. * per ALLOCATE and GROW.
  101. */
  102. #ifdef JS_ARENA_CONST_ALIGN_MASK
  103. #define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \
  104. & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK)
  105. #define JS_INIT_ARENA_POOL(pool, name, size, quotap) \
  106. JS_INIT_NAMED_ARENA_POOL(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1, \
  107. quotap)
  108. #else
  109. #define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
  110. #define JS_INIT_ARENA_POOL(pool, name, size, align, quotap) \
  111. JS_INIT_NAMED_ARENA_POOL(pool, name, size, align, quotap)
  112. #endif
  113. #define JS_ARENA_ALLOCATE(p, pool, nb) \
  114. JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
  115. #define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \
  116. JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0)
  117. #define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \
  118. JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit)
  119. /*
  120. * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
  121. * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
  122. * address space (possible when running a 32-bit program on a 64-bit system
  123. * where the kernel maps the heap up against the top of the 32-bit address
  124. * space).
  125. *
  126. * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
  127. * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
  128. */
  129. #define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard) \
  130. JS_BEGIN_MACRO \
  131. JSArena *_a = (pool)->current; \
  132. size_t _nb = JS_ARENA_ALIGN(pool, nb); \
  133. jsuword _p = _a->avail; \
  134. if ((guard) || _p > _a->limit - _nb) \
  135. _p = (jsuword)JS_ArenaAllocate(pool, _nb); \
  136. else \
  137. _a->avail = _p + _nb; \
  138. p = (type) _p; \
  139. JS_ArenaCountAllocation(pool, nb); \
  140. JS_END_MACRO
  141. #define JS_ARENA_GROW(p, pool, size, incr) \
  142. JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
  143. #define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \
  144. JS_BEGIN_MACRO \
  145. JSArena *_a = (pool)->current; \
  146. if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \
  147. size_t _nb = (size) + (incr); \
  148. _nb = JS_ARENA_ALIGN(pool, _nb); \
  149. if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) { \
  150. _a->avail = (jsuword)(p) + _nb; \
  151. JS_ArenaCountInplaceGrowth(pool, size, incr); \
  152. } else if ((jsuword)(p) == _a->base) { \
  153. p = (type) JS_ArenaRealloc(pool, p, size, incr); \
  154. } else { \
  155. p = (type) JS_ArenaGrow(pool, p, size, incr); \
  156. } \
  157. } else { \
  158. p = (type) JS_ArenaGrow(pool, p, size, incr); \
  159. } \
  160. JS_ArenaCountGrowth(pool, size, incr); \
  161. JS_END_MACRO
  162. #define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail)
  163. #define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q))
  164. /*
  165. * Check if the mark is inside arena's allocated area.
  166. */
  167. #define JS_ARENA_MARK_MATCH(a, mark) \
  168. (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
  169. #ifdef DEBUG
  170. #define JS_FREE_PATTERN 0xDA
  171. #define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
  172. memset((void*)(a)->avail, JS_FREE_PATTERN, \
  173. (a)->limit - (a)->avail))
  174. #define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \
  175. (a)->limit - (jsuword)(a))
  176. #else
  177. #define JS_CLEAR_UNUSED(a) /* nothing */
  178. #define JS_CLEAR_ARENA(a) /* nothing */
  179. #endif
  180. #define JS_ARENA_RELEASE(pool, mark) \
  181. JS_BEGIN_MACRO \
  182. char *_m = (char *)(mark); \
  183. JSArena *_a = (pool)->current; \
  184. if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) { \
  185. _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \
  186. JS_ASSERT(_a->avail <= _a->limit); \
  187. JS_CLEAR_UNUSED(_a); \
  188. JS_ArenaCountRetract(pool, _m); \
  189. } else { \
  190. JS_ArenaRelease(pool, _m); \
  191. } \
  192. JS_ArenaCountRelease(pool, _m); \
  193. JS_END_MACRO
  194. #ifdef JS_ARENAMETER
  195. #define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
  196. #else
  197. #define JS_COUNT_ARENA(pool,op)
  198. #endif
  199. #define JS_ARENA_DESTROY(pool, a, pnext) \
  200. JS_BEGIN_MACRO \
  201. JS_COUNT_ARENA(pool,--); \
  202. if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
  203. *(pnext) = (a)->next; \
  204. JS_CLEAR_ARENA(a); \
  205. free(a); \
  206. (a) = NULL; \
  207. JS_END_MACRO
  208. /*
  209. * Initialize an arena pool with a minimum size per arena of size bytes.
  210. * Always call JS_SET_ARENA_METER_NAME before calling this or use
  211. * JS_INIT_ARENA_POOL macro to provide a name for for debugging and metering.
  212. */
  213. extern JS_PUBLIC_API(void)
  214. JS_INIT_NAMED_ARENA_POOL(JSArenaPool *pool, const char *name, size_t size,
  215. size_t align, size_t *quotap);
  216. /*
  217. * Free the arenas in pool. The user may continue to allocate from pool
  218. * after calling this function. There is no need to call JS_InitArenaPool()
  219. * again unless JS_FinishArenaPool(pool) has been called.
  220. */
  221. extern JS_PUBLIC_API(void)
  222. JS_FreeArenaPool(JSArenaPool *pool);
  223. /*
  224. * Free the arenas in pool and finish using it altogether.
  225. */
  226. extern JS_PUBLIC_API(void)
  227. JS_FinishArenaPool(JSArenaPool *pool);
  228. /*
  229. * Deprecated do-nothing function.
  230. */
  231. extern JS_PUBLIC_API(void)
  232. JS_ArenaFinish(void);
  233. /*
  234. * Deprecated do-nothing function.
  235. */
  236. extern JS_PUBLIC_API(void)
  237. JS_ArenaShutDown(void);
  238. /*
  239. * Friend functions used by the JS_ARENA_*() macros.
  240. */
  241. extern JS_PUBLIC_API(void *)
  242. JS_ArenaAllocate(JSArenaPool *pool, size_t nb);
  243. extern JS_PUBLIC_API(void *)
  244. JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
  245. extern JS_PUBLIC_API(void *)
  246. JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
  247. extern JS_PUBLIC_API(void)
  248. JS_ArenaRelease(JSArenaPool *pool, char *mark);
  249. #ifdef JS_ARENAMETER
  250. #include <stdio.h>
  251. extern JS_PUBLIC_API(void)
  252. JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
  253. extern JS_PUBLIC_API(void)
  254. JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
  255. extern JS_PUBLIC_API(void)
  256. JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
  257. extern JS_PUBLIC_API(void)
  258. JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
  259. extern JS_PUBLIC_API(void)
  260. JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
  261. extern JS_PUBLIC_API(void)
  262. JS_DumpArenaStats(FILE *fp);
  263. #else /* !JS_ARENAMETER */
  264. #define JS_ArenaCountAllocation(ap, nb) /* nothing */
  265. #define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
  266. #define JS_ArenaCountGrowth(ap, size, incr) /* nothing */
  267. #define JS_ArenaCountRelease(ap, mark) /* nothing */
  268. #define JS_ArenaCountRetract(ap, mark) /* nothing */
  269. #endif /* !JS_ARENAMETER */
  270. JS_END_EXTERN_C
  271. #endif /* jsarena_h___ */