lmem.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. ** $Id: $
  3. ** Interface to Memory Manager
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #include "lmem.h"
  8. #include "lua.h"
  9. int luaM_growaux (void **block, unsigned long nelems, int size,
  10. char *errormsg, unsigned long limit)
  11. {
  12. if (nelems >= limit)
  13. lua_error(errormsg);
  14. nelems = (nelems == 0) ? 32 : nelems*2;
  15. if (nelems > limit)
  16. nelems = limit;
  17. *block = luaM_realloc(*block, nelems*size);
  18. return (int)nelems;
  19. }
  20. static unsigned long Mbuffsize = 0;
  21. static char *Mbuffer = NULL;
  22. void *luaM_buffer (unsigned long size)
  23. {
  24. if (size > Mbuffsize) {
  25. Mbuffsize = size;
  26. Mbuffer = luaM_realloc(Mbuffer, Mbuffsize);
  27. }
  28. return Mbuffer;
  29. }
  30. void luaM_clearbuffer (void)
  31. {
  32. Mbuffsize /= 2;
  33. Mbuffer = luaM_realloc(Mbuffer, Mbuffsize);
  34. }
  35. #ifndef DEBUG
  36. /*
  37. ** generic allocation routine.
  38. ** real ANSI systems do not need some of these tests,
  39. ** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b).
  40. ** But some systems (e.g. Sun OS) are not that ANSI...
  41. */
  42. void *luaM_realloc (void *block, unsigned long size)
  43. {
  44. size_t s = (size_t)size;
  45. if (s != size)
  46. lua_error("Allocation Error: Block too big");
  47. if (size == 0) {
  48. if (block) {
  49. free(block);
  50. }
  51. return NULL;
  52. }
  53. block = block ? realloc(block, s) : malloc(s);
  54. if (block == NULL)
  55. lua_error(memEM);
  56. return block;
  57. }
  58. #else
  59. /* DEBUG */
  60. #include <assert.h>
  61. #include <string.h>
  62. #define MARK 55
  63. static unsigned long numblocks = 0;
  64. static unsigned long totalmem = 0;
  65. void luaM_query (void)
  66. {
  67. lua_pushnumber(totalmem);
  68. lua_pushnumber(numblocks);
  69. }
  70. static void *checkblock (void *block)
  71. {
  72. unsigned long *b = (unsigned long *)block - 1;
  73. unsigned long size = *b;
  74. assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK);
  75. numblocks--;
  76. totalmem -= size;
  77. return b;
  78. }
  79. void *luaM_realloc (void *block, unsigned long size)
  80. {
  81. unsigned long realsize = sizeof(unsigned long)+size+sizeof(char);
  82. if (realsize != (size_t)realsize)
  83. lua_error("Allocation Error: Block too big");
  84. if (size == 0) { /* ANSI doen't need this, but some machines... */
  85. if (block) {
  86. memset(block, -1, *((unsigned long *)block-1)); /* erase block */
  87. block = checkblock(block);
  88. free(block);
  89. }
  90. return NULL;
  91. }
  92. if (block) {
  93. block = checkblock(block);
  94. block = (unsigned long *)realloc(block, realsize);
  95. }
  96. else
  97. block = (unsigned long *)malloc(realsize);
  98. if (block == NULL)
  99. lua_error(memEM);
  100. totalmem += size;
  101. numblocks++;
  102. *(unsigned long *)block = size;
  103. *(((char *)block)+size+sizeof(unsigned long)) = MARK;
  104. return (unsigned long *)block+1;
  105. }
  106. #endif