gc-malloc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #include <string.h>
  23. #ifdef __ia64__
  24. #include <ucontext.h>
  25. extern unsigned long * __libc_ia64_register_backing_store_base;
  26. #endif
  27. #include "libguile/_scm.h"
  28. #include "libguile/eval.h"
  29. #include "libguile/stime.h"
  30. #include "libguile/stackchk.h"
  31. #include "libguile/struct.h"
  32. #include "libguile/smob.h"
  33. #include "libguile/unif.h"
  34. #include "libguile/async.h"
  35. #include "libguile/ports.h"
  36. #include "libguile/root.h"
  37. #include "libguile/strings.h"
  38. #include "libguile/vectors.h"
  39. #include "libguile/weaks.h"
  40. #include "libguile/hashtab.h"
  41. #include "libguile/tags.h"
  42. #include "libguile/validate.h"
  43. #include "libguile/deprecation.h"
  44. #include "libguile/gc.h"
  45. #include "libguile/private-gc.h"
  46. #ifdef GUILE_DEBUG_MALLOC
  47. #include "libguile/debug-malloc.h"
  48. #endif
  49. #ifdef HAVE_MALLOC_H
  50. #include <malloc.h>
  51. #endif
  52. #ifdef HAVE_UNISTD_H
  53. #include <unistd.h>
  54. #endif
  55. /*
  56. INIT_MALLOC_LIMIT is the initial amount of malloc usage which will
  57. trigger a GC.
  58. After startup (at the guile> prompt), we have approximately 100k of
  59. alloced memory, which won't go away on GC. Let's set the init such
  60. that we get a nice yield on the next allocation:
  61. */
  62. #define SCM_DEFAULT_INIT_MALLOC_LIMIT 200*1024
  63. #define SCM_DEFAULT_MALLOC_MINYIELD 40
  64. /* #define DEBUGINFO */
  65. static int scm_i_minyield_malloc;
  66. void
  67. scm_gc_init_malloc (void)
  68. {
  69. scm_mtrigger = scm_getenv_int ("GUILE_INIT_MALLOC_LIMIT",
  70. SCM_DEFAULT_INIT_MALLOC_LIMIT);
  71. scm_i_minyield_malloc = scm_getenv_int ("GUILE_MIN_YIELD_MALLOC",
  72. SCM_DEFAULT_MALLOC_MINYIELD);
  73. if (scm_i_minyield_malloc >= 100)
  74. scm_i_minyield_malloc = 99;
  75. if (scm_i_minyield_malloc < 1)
  76. scm_i_minyield_malloc = 1;
  77. if (scm_mtrigger < 0)
  78. scm_mtrigger = SCM_DEFAULT_INIT_MALLOC_LIMIT;
  79. }
  80. /* Function for non-cell memory management.
  81. */
  82. void *
  83. scm_realloc (void *mem, size_t size)
  84. {
  85. void *ptr;
  86. SCM_SYSCALL (ptr = realloc (mem, size));
  87. if (ptr)
  88. return ptr;
  89. scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
  90. scm_gc_running_p = 1;
  91. scm_i_sweep_all_segments ("realloc");
  92. SCM_SYSCALL (ptr = realloc (mem, size));
  93. if (ptr)
  94. {
  95. scm_gc_running_p = 0;
  96. scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex);
  97. return ptr;
  98. }
  99. scm_i_gc ("realloc");
  100. scm_i_sweep_all_segments ("realloc");
  101. scm_gc_running_p = 0;
  102. scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex);
  103. SCM_SYSCALL (ptr = realloc (mem, size));
  104. if (ptr)
  105. return ptr;
  106. scm_memory_error ("realloc");
  107. }
  108. void *
  109. scm_malloc (size_t sz)
  110. {
  111. return scm_realloc (NULL, sz);
  112. }
  113. /*
  114. Hmm. Should we use the C convention for arguments (i.e. N_ELTS,
  115. SIZEOF_ELT)? --hwn
  116. */
  117. void *
  118. scm_calloc (size_t sz)
  119. {
  120. void * ptr;
  121. /*
  122. By default, try to use calloc, as it is likely more efficient than
  123. calling memset by hand.
  124. */
  125. SCM_SYSCALL (ptr = calloc (sz, 1));
  126. if (ptr)
  127. return ptr;
  128. ptr = scm_realloc (NULL, sz);
  129. memset (ptr, 0x0, sz);
  130. return ptr;
  131. }
  132. char *
  133. scm_strndup (const char *str, size_t n)
  134. {
  135. char *dst = scm_malloc (n + 1);
  136. memcpy (dst, str, n);
  137. dst[n] = 0;
  138. return dst;
  139. }
  140. char *
  141. scm_strdup (const char *str)
  142. {
  143. return scm_strndup (str, strlen (str));
  144. }
  145. static void
  146. decrease_mtrigger (size_t size, const char * what)
  147. {
  148. scm_i_pthread_mutex_lock (&scm_i_gc_admin_mutex);
  149. if (size > scm_mallocated)
  150. {
  151. fprintf (stderr, "`scm_mallocated' underflow. This means that more "
  152. "memory was unregistered\n"
  153. "via `scm_gc_unregister_collectable_memory ()' than "
  154. "registered.\n");
  155. abort ();
  156. }
  157. scm_mallocated -= size;
  158. scm_gc_malloc_collected += size;
  159. scm_i_pthread_mutex_unlock (&scm_i_gc_admin_mutex);
  160. }
  161. static void
  162. increase_mtrigger (size_t size, const char *what)
  163. {
  164. size_t mallocated = 0;
  165. int overflow = 0, triggered = 0;
  166. scm_i_pthread_mutex_lock (&scm_i_gc_admin_mutex);
  167. if (ULONG_MAX - size < scm_mallocated)
  168. overflow = 1;
  169. else
  170. {
  171. scm_mallocated += size;
  172. mallocated = scm_mallocated;
  173. if (scm_mallocated > scm_mtrigger)
  174. triggered = 1;
  175. }
  176. scm_i_pthread_mutex_unlock (&scm_i_gc_admin_mutex);
  177. if (overflow)
  178. scm_memory_error ("Overflow of scm_mallocated: too much memory in use.");
  179. /*
  180. A program that uses a lot of malloced collectable memory (vectors,
  181. strings), will use a lot of memory off the cell-heap; it needs to
  182. do GC more often (before cells are exhausted), otherwise swapping
  183. and malloc management will tie it down.
  184. */
  185. if (triggered)
  186. {
  187. unsigned long prev_alloced;
  188. float yield;
  189. scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
  190. scm_gc_running_p = 1;
  191. prev_alloced = mallocated;
  192. scm_i_gc (what);
  193. scm_i_sweep_all_segments ("mtrigger");
  194. yield = (((float) prev_alloced - (float) scm_mallocated)
  195. / (float) prev_alloced);
  196. scm_gc_malloc_yield_percentage = (int) (100 * yield);
  197. #ifdef DEBUGINFO
  198. fprintf (stderr, "prev %lud , now %lud, yield %4.2lf, want %d",
  199. prev_alloced,
  200. scm_mallocated,
  201. 100.0 * yield,
  202. scm_i_minyield_malloc);
  203. #endif
  204. if (yield < scm_i_minyield_malloc / 100.0)
  205. {
  206. /*
  207. We make the trigger a little larger, even; If you have a
  208. program that builds up a lot of data in strings, then the
  209. desired yield will never be satisfied.
  210. Instead of getting bogged down, we let the mtrigger grow
  211. strongly with it.
  212. */
  213. float no_overflow_trigger = scm_mallocated * 110.0;
  214. no_overflow_trigger /= (float) (100.0 - scm_i_minyield_malloc);
  215. if (no_overflow_trigger >= (float) ULONG_MAX)
  216. scm_mtrigger = ULONG_MAX;
  217. else
  218. scm_mtrigger = (unsigned long) no_overflow_trigger;
  219. #ifdef DEBUGINFO
  220. fprintf (stderr, "Mtrigger sweep: ineffective. New trigger %d\n",
  221. scm_mtrigger);
  222. #endif
  223. }
  224. scm_gc_running_p = 0;
  225. scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex);
  226. }
  227. }
  228. void
  229. scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
  230. {
  231. increase_mtrigger (size, what);
  232. #ifdef GUILE_DEBUG_MALLOC
  233. if (mem)
  234. scm_malloc_register (mem, what);
  235. #endif
  236. }
  237. void
  238. scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what)
  239. {
  240. decrease_mtrigger (size, what);
  241. #ifdef GUILE_DEBUG_MALLOC
  242. if (mem)
  243. scm_malloc_unregister (mem);
  244. #endif
  245. }
  246. void *
  247. scm_gc_malloc (size_t size, const char *what)
  248. {
  249. /*
  250. The straightforward implementation below has the problem
  251. that it might call the GC twice, once in scm_malloc and then
  252. again in scm_gc_register_collectable_memory. We don't really
  253. want the second GC since it will not find new garbage.
  254. Note: this is a theoretical peeve. In reality, malloc() never
  255. returns NULL. Usually, memory is overcommitted, and when you try
  256. to write it the program is killed with signal 11. --hwn
  257. */
  258. void *ptr = size ? scm_malloc (size) : NULL;
  259. scm_gc_register_collectable_memory (ptr, size, what);
  260. return ptr;
  261. }
  262. void *
  263. scm_gc_calloc (size_t size, const char *what)
  264. {
  265. void *ptr = scm_gc_malloc (size, what);
  266. memset (ptr, 0x0, size);
  267. return ptr;
  268. }
  269. void *
  270. scm_gc_realloc (void *mem, size_t old_size, size_t new_size, const char *what)
  271. {
  272. void *ptr;
  273. /* XXX - see scm_gc_malloc. */
  274. /*
  275. scm_realloc() may invalidate the block pointed to by WHERE, eg. by
  276. unmapping it from memory or altering the contents. Since
  277. increase_mtrigger() might trigger a GC that would scan
  278. MEM, it is crucial that this call precedes realloc().
  279. */
  280. decrease_mtrigger (old_size, what);
  281. increase_mtrigger (new_size, what);
  282. ptr = scm_realloc (mem, new_size);
  283. #ifdef GUILE_DEBUG_MALLOC
  284. if (mem)
  285. scm_malloc_reregister (mem, ptr, what);
  286. #endif
  287. return ptr;
  288. }
  289. void
  290. scm_gc_free (void *mem, size_t size, const char *what)
  291. {
  292. scm_gc_unregister_collectable_memory (mem, size, what);
  293. if (mem)
  294. free (mem);
  295. }
  296. char *
  297. scm_gc_strndup (const char *str, size_t n, const char *what)
  298. {
  299. char *dst = scm_gc_malloc (n+1, what);
  300. memcpy (dst, str, n);
  301. dst[n] = 0;
  302. return dst;
  303. }
  304. char *
  305. scm_gc_strdup (const char *str, const char *what)
  306. {
  307. return scm_gc_strndup (str, strlen (str), what);
  308. }
  309. #if SCM_ENABLE_DEPRECATED == 1
  310. /* {Deprecated front end to malloc}
  311. *
  312. * scm_must_malloc, scm_must_realloc, scm_must_free, scm_done_malloc,
  313. * scm_done_free
  314. *
  315. * These functions provide services comparable to malloc, realloc, and
  316. * free. They should be used when allocating memory that will be under
  317. * control of the garbage collector, i.e., if the memory may be freed
  318. * during garbage collection.
  319. *
  320. * They are deprecated because they weren't really used the way
  321. * outlined above, and making sure to return the right amount from
  322. * smob free routines was sometimes difficult when dealing with nested
  323. * data structures. We basically want everybody to review their code
  324. * and use the more symmetrical scm_gc_malloc/scm_gc_free functions
  325. * instead. In some cases, where scm_must_malloc has been used
  326. * incorrectly (i.e. for non-GC-able memory), use scm_malloc/free.
  327. */
  328. void *
  329. scm_must_malloc (size_t size, const char *what)
  330. {
  331. scm_c_issue_deprecation_warning
  332. ("scm_must_malloc is deprecated. "
  333. "Use scm_gc_malloc and scm_gc_free instead.");
  334. return scm_gc_malloc (size, what);
  335. }
  336. void *
  337. scm_must_realloc (void *where,
  338. size_t old_size,
  339. size_t size,
  340. const char *what)
  341. {
  342. scm_c_issue_deprecation_warning
  343. ("scm_must_realloc is deprecated. "
  344. "Use scm_gc_realloc and scm_gc_free instead.");
  345. return scm_gc_realloc (where, old_size, size, what);
  346. }
  347. char *
  348. scm_must_strndup (const char *str, size_t length)
  349. {
  350. scm_c_issue_deprecation_warning
  351. ("scm_must_strndup is deprecated. "
  352. "Use scm_gc_strndup and scm_gc_free instead.");
  353. return scm_gc_strndup (str, length, "string");
  354. }
  355. char *
  356. scm_must_strdup (const char *str)
  357. {
  358. scm_c_issue_deprecation_warning
  359. ("scm_must_strdup is deprecated. "
  360. "Use scm_gc_strdup and scm_gc_free instead.");
  361. return scm_gc_strdup (str, "string");
  362. }
  363. void
  364. scm_must_free (void *obj)
  365. #define FUNC_NAME "scm_must_free"
  366. {
  367. scm_c_issue_deprecation_warning
  368. ("scm_must_free is deprecated. "
  369. "Use scm_gc_malloc and scm_gc_free instead.");
  370. #ifdef GUILE_DEBUG_MALLOC
  371. scm_malloc_unregister (obj);
  372. #endif
  373. if (obj)
  374. free (obj);
  375. else
  376. {
  377. fprintf (stderr,"freeing NULL pointer");
  378. abort ();
  379. }
  380. }
  381. #undef FUNC_NAME
  382. void
  383. scm_done_malloc (long size)
  384. {
  385. scm_c_issue_deprecation_warning
  386. ("scm_done_malloc is deprecated. "
  387. "Use scm_gc_register_collectable_memory instead.");
  388. if (size >= 0)
  389. scm_gc_register_collectable_memory (NULL, size, "foreign mallocs");
  390. else
  391. scm_gc_unregister_collectable_memory (NULL, -size, "foreign mallocs");
  392. }
  393. void
  394. scm_done_free (long size)
  395. {
  396. scm_c_issue_deprecation_warning
  397. ("scm_done_free is deprecated. "
  398. "Use scm_gc_unregister_collectable_memory instead.");
  399. if (size >= 0)
  400. scm_gc_unregister_collectable_memory (NULL, size, "foreign mallocs");
  401. else
  402. scm_gc_register_collectable_memory (NULL, -size, "foreign mallocs");
  403. }
  404. #endif /* SCM_ENABLE_DEPRECATED == 1 */