new_hblk.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3. * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
  4. * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved.
  5. *
  6. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  7. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  8. *
  9. * Permission is hereby granted to use or copy this program
  10. * for any purpose, provided the above notices are retained on all copies.
  11. * Permission to modify the code and to distribute modified code is granted,
  12. * provided the above notices are retained, and a notice that the code was
  13. * modified is included with the above copyright notice.
  14. */
  15. #include "private/gc_priv.h"
  16. /*
  17. * This file contains the functions:
  18. * ptr_t GC_build_flXXX(h, old_fl)
  19. * void GC_new_hblk(size)
  20. */
  21. #include <stdio.h>
  22. #ifndef SMALL_CONFIG
  23. /* Build a free list for size 2 (words) cleared objects inside */
  24. /* hblk h. Set the last link to be ofl. Return a pointer to the */
  25. /* first free list entry. */
  26. STATIC ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl)
  27. {
  28. word * p = (word *)(h -> hb_body);
  29. word * lim = (word *)(h + 1);
  30. p[0] = (word)ofl;
  31. p[1] = 0;
  32. p[2] = (word)p;
  33. p[3] = 0;
  34. p += 4;
  35. for (; (word)p < (word)lim; p += 4) {
  36. p[0] = (word)(p-2);
  37. p[1] = 0;
  38. p[2] = (word)p;
  39. p[3] = 0;
  40. };
  41. return((ptr_t)(p-2));
  42. }
  43. /* The same for size 4 cleared objects. */
  44. STATIC ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl)
  45. {
  46. word * p = (word *)(h -> hb_body);
  47. word * lim = (word *)(h + 1);
  48. p[0] = (word)ofl;
  49. p[1] = 0;
  50. p[2] = 0;
  51. p[3] = 0;
  52. p += 4;
  53. for (; (word)p < (word)lim; p += 4) {
  54. GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
  55. p[0] = (word)(p-4);
  56. p[1] = 0;
  57. CLEAR_DOUBLE(p+2);
  58. };
  59. return((ptr_t)(p-4));
  60. }
  61. /* The same for size 2 uncleared objects. */
  62. STATIC ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl)
  63. {
  64. word * p = (word *)(h -> hb_body);
  65. word * lim = (word *)(h + 1);
  66. p[0] = (word)ofl;
  67. p[2] = (word)p;
  68. p += 4;
  69. for (; (word)p < (word)lim; p += 4) {
  70. p[0] = (word)(p-2);
  71. p[2] = (word)p;
  72. };
  73. return((ptr_t)(p-2));
  74. }
  75. /* The same for size 4 uncleared objects. */
  76. STATIC ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl)
  77. {
  78. word * p = (word *)(h -> hb_body);
  79. word * lim = (word *)(h + 1);
  80. p[0] = (word)ofl;
  81. p[4] = (word)p;
  82. p += 8;
  83. for (; (word)p < (word)lim; p += 8) {
  84. GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
  85. p[0] = (word)(p-4);
  86. p[4] = (word)p;
  87. };
  88. return((ptr_t)(p-4));
  89. }
  90. #endif /* !SMALL_CONFIG */
  91. /* Build a free list for objects of size sz inside heap block h. */
  92. /* Clear objects inside h if clear is set. Add list to the end of */
  93. /* the free list we build. Return the new free list. */
  94. /* This could be called without the main GC lock, if we ensure that */
  95. /* there is no concurrent collection which might reclaim objects that */
  96. /* we have not yet allocated. */
  97. GC_INNER ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear,
  98. ptr_t list)
  99. {
  100. word *p, *prev;
  101. word *last_object; /* points to last object in new hblk */
  102. /* Do a few prefetches here, just because its cheap. */
  103. /* If we were more serious about it, these should go inside */
  104. /* the loops. But write prefetches usually don't seem to */
  105. /* matter much. */
  106. GC_PREFETCH_FOR_WRITE((ptr_t)h);
  107. GC_PREFETCH_FOR_WRITE((ptr_t)h + 128);
  108. GC_PREFETCH_FOR_WRITE((ptr_t)h + 256);
  109. GC_PREFETCH_FOR_WRITE((ptr_t)h + 378);
  110. # ifndef SMALL_CONFIG
  111. /* Handle small objects sizes more efficiently. For larger objects */
  112. /* the difference is less significant. */
  113. switch (sz) {
  114. case 2: if (clear) {
  115. return GC_build_fl_clear2(h, list);
  116. } else {
  117. return GC_build_fl2(h, list);
  118. }
  119. case 4: if (clear) {
  120. return GC_build_fl_clear4(h, list);
  121. } else {
  122. return GC_build_fl4(h, list);
  123. }
  124. default:
  125. break;
  126. }
  127. # endif /* !SMALL_CONFIG */
  128. /* Clear the page if necessary. */
  129. if (clear) BZERO(h, HBLKSIZE);
  130. /* Add objects to free list */
  131. p = (word *)(h -> hb_body) + sz; /* second object in *h */
  132. prev = (word *)(h -> hb_body); /* One object behind p */
  133. last_object = (word *)((char *)h + HBLKSIZE);
  134. last_object -= sz;
  135. /* Last place for last object to start */
  136. /* make a list of all objects in *h with head as last object */
  137. while ((word)p <= (word)last_object) {
  138. /* current object's link points to last object */
  139. obj_link(p) = (ptr_t)prev;
  140. prev = p;
  141. p += sz;
  142. }
  143. p -= sz; /* p now points to last object */
  144. /* Put p (which is now head of list of objects in *h) as first */
  145. /* pointer in the appropriate free list for this size. */
  146. *(ptr_t *)h = list;
  147. return ((ptr_t)p);
  148. }
  149. /* Allocate a new heapblock for small objects of size gran granules. */
  150. /* Add all of the heapblock's objects to the free list for objects */
  151. /* of that size. Set all mark bits if objects are uncollectible. */
  152. /* Will fail to do anything if we are out of memory. */
  153. GC_INNER void GC_new_hblk(size_t gran, int kind)
  154. {
  155. struct hblk *h; /* the new heap block */
  156. GC_bool clear = GC_obj_kinds[kind].ok_init;
  157. GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE);
  158. if (GC_debugging_started) clear = TRUE;
  159. /* Allocate a new heap block */
  160. h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0);
  161. if (h == 0) return;
  162. /* Mark all objects if appropriate. */
  163. if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
  164. /* Build the free list */
  165. GC_obj_kinds[kind].ok_freelist[gran] =
  166. GC_build_fl(h, GRANULES_TO_WORDS(gran), clear,
  167. (ptr_t)GC_obj_kinds[kind].ok_freelist[gran]);
  168. }