You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
5.5 KiB

  1. #include "Python.h"
  2. /* A simple arena block structure.
  3. Measurements with standard library modules suggest the average
  4. allocation is about 20 bytes and that most compiles use a single
  5. block.
  6. TODO(jhylton): Think about a realloc API, maybe just for the last
  7. allocation?
  8. */
  9. #define DEFAULT_BLOCK_SIZE 8192
  10. #define ALIGNMENT 8
  11. typedef struct _block {
  12. /* Total number of bytes owned by this block available to pass out.
  13. * Read-only after initialization. The first such byte starts at
  14. * ab_mem.
  15. */
  16. size_t ab_size;
  17. /* Total number of bytes already passed out. The next byte available
  18. * to pass out starts at ab_mem + ab_offset.
  19. */
  20. size_t ab_offset;
  21. /* An arena maintains a singly-linked, NULL-terminated list of
  22. * all blocks owned by the arena. These are linked via the
  23. * ab_next member.
  24. */
  25. struct _block *ab_next;
  26. /* Pointer to the first allocatable byte owned by this block. Read-
  27. * only after initialization.
  28. */
  29. void *ab_mem;
  30. } block;
  31. /* The arena manages two kinds of memory, blocks of raw memory
  32. and a list of PyObject* pointers. PyObjects are decrefed
  33. when the arena is freed.
  34. */
  35. struct _arena {
  36. /* Pointer to the first block allocated for the arena, never NULL.
  37. It is used only to find the first block when the arena is
  38. being freed.
  39. */
  40. block *a_head;
  41. /* Pointer to the block currently used for allocation. It's
  42. ab_next field should be NULL. If it is not-null after a
  43. call to block_alloc(), it means a new block has been allocated
  44. and a_cur should be reset to point it.
  45. */
  46. block *a_cur;
  47. /* A Python list object containing references to all the PyObject
  48. pointers associated with this area. They will be DECREFed
  49. when the arena is freed.
  50. */
  51. PyObject *a_objects;
  52. #if defined(Py_DEBUG)
  53. /* Debug output */
  54. size_t total_allocs;
  55. size_t total_size;
  56. size_t total_blocks;
  57. size_t total_block_size;
  58. size_t total_big_blocks;
  59. #endif
  60. };
  61. static block *
  62. block_new(size_t size)
  63. {
  64. /* Allocate header and block as one unit.
  65. ab_mem points just past header. */
  66. block *b = (block *)PyMem_Malloc(sizeof(block) + size);
  67. if (!b)
  68. return NULL;
  69. b->ab_size = size;
  70. b->ab_mem = (void *)(b + 1);
  71. b->ab_next = NULL;
  72. b->ab_offset = (char *)_Py_ALIGN_UP(b->ab_mem, ALIGNMENT) -
  73. (char *)(b->ab_mem);
  74. return b;
  75. }
  76. static void
  77. block_free(block *b) {
  78. while (b) {
  79. block *next = b->ab_next;
  80. PyMem_Free(b);
  81. b = next;
  82. }
  83. }
  84. static void *
  85. block_alloc(block *b, size_t size)
  86. {
  87. void *p;
  88. assert(b);
  89. size = _Py_SIZE_ROUND_UP(size, ALIGNMENT);
  90. if (b->ab_offset + size > b->ab_size) {
  91. /* If we need to allocate more memory than will fit in
  92. the default block, allocate a one-off block that is
  93. exactly the right size. */
  94. /* TODO(jhylton): Think about space waste at end of block */
  95. block *newbl = block_new(
  96. size < DEFAULT_BLOCK_SIZE ?
  97. DEFAULT_BLOCK_SIZE : size);
  98. if (!newbl)
  99. return NULL;
  100. assert(!b->ab_next);
  101. b->ab_next = newbl;
  102. b = newbl;
  103. }
  104. assert(b->ab_offset + size <= b->ab_size);
  105. p = (void *)(((char *)b->ab_mem) + b->ab_offset);
  106. b->ab_offset += size;
  107. return p;
  108. }
  109. PyArena *
  110. PyArena_New()
  111. {
  112. PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena));
  113. if (!arena)
  114. return (PyArena*)PyErr_NoMemory();
  115. arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
  116. arena->a_cur = arena->a_head;
  117. if (!arena->a_head) {
  118. PyMem_Free((void *)arena);
  119. return (PyArena*)PyErr_NoMemory();
  120. }
  121. arena->a_objects = PyList_New(0);
  122. if (!arena->a_objects) {
  123. block_free(arena->a_head);
  124. PyMem_Free((void *)arena);
  125. return (PyArena*)PyErr_NoMemory();
  126. }
  127. #if defined(Py_DEBUG)
  128. arena->total_allocs = 0;
  129. arena->total_size = 0;
  130. arena->total_blocks = 1;
  131. arena->total_block_size = DEFAULT_BLOCK_SIZE;
  132. arena->total_big_blocks = 0;
  133. #endif
  134. return arena;
  135. }
  136. void
  137. PyArena_Free(PyArena *arena)
  138. {
  139. assert(arena);
  140. #if defined(Py_DEBUG)
  141. /*
  142. fprintf(stderr,
  143. "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
  144. arena->total_allocs, arena->total_size, arena->total_blocks,
  145. arena->total_block_size, arena->total_big_blocks,
  146. PyList_Size(arena->a_objects));
  147. */
  148. #endif
  149. block_free(arena->a_head);
  150. /* This property normally holds, except when the code being compiled
  151. is sys.getobjects(0), in which case there will be two references.
  152. assert(arena->a_objects->ob_refcnt == 1);
  153. */
  154. Py_DECREF(arena->a_objects);
  155. PyMem_Free(arena);
  156. }
  157. void *
  158. PyArena_Malloc(PyArena *arena, size_t size)
  159. {
  160. void *p = block_alloc(arena->a_cur, size);
  161. if (!p)
  162. return PyErr_NoMemory();
  163. #if defined(Py_DEBUG)
  164. arena->total_allocs++;
  165. arena->total_size += size;
  166. #endif
  167. /* Reset cur if we allocated a new block. */
  168. if (arena->a_cur->ab_next) {
  169. arena->a_cur = arena->a_cur->ab_next;
  170. #if defined(Py_DEBUG)
  171. arena->total_blocks++;
  172. arena->total_block_size += arena->a_cur->ab_size;
  173. if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
  174. ++arena->total_big_blocks;
  175. #endif
  176. }
  177. return p;
  178. }
  179. int
  180. PyArena_AddPyObject(PyArena *arena, PyObject *obj)
  181. {
  182. int r = PyList_Append(arena->a_objects, obj);
  183. if (r >= 0) {
  184. Py_DECREF(obj);
  185. }
  186. return r;
  187. }