obj_map.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3. * Copyright (c) 1991, 1992 by Xerox Corporation. All rights reserved.
  4. * Copyright (c) 1999-2001 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. /* Routines for maintaining maps describing heap block
  16. * layouts for various object sizes. Allows fast pointer validity checks
  17. * and fast location of object start locations on machines (such as SPARC)
  18. * with slow division.
  19. */
  20. # include "private/gc_priv.h"
  21. map_entry_type * GC_invalid_map = 0;
  22. /* Invalidate the object map associated with a block. Free blocks */
  23. /* are identified by invalid maps. */
  24. void GC_invalidate_map(hhdr)
  25. hdr *hhdr;
  26. {
  27. register int displ;
  28. if (GC_invalid_map == 0) {
  29. GC_invalid_map = (map_entry_type *)GC_scratch_alloc(MAP_SIZE);
  30. if (GC_invalid_map == 0) {
  31. GC_err_printf0(
  32. "Cant initialize GC_invalid_map: insufficient memory\n");
  33. EXIT();
  34. }
  35. for (displ = 0; displ < HBLKSIZE; displ++) {
  36. MAP_ENTRY(GC_invalid_map, displ) = OBJ_INVALID;
  37. }
  38. }
  39. hhdr -> hb_map = GC_invalid_map;
  40. }
  41. /* Consider pointers that are offset bytes displaced from the beginning */
  42. /* of an object to be valid. */
  43. # if defined(__STDC__) || defined(__cplusplus)
  44. void GC_register_displacement(GC_word offset)
  45. # else
  46. void GC_register_displacement(offset)
  47. GC_word offset;
  48. # endif
  49. {
  50. DCL_LOCK_STATE;
  51. DISABLE_SIGNALS();
  52. LOCK();
  53. GC_register_displacement_inner(offset);
  54. UNLOCK();
  55. ENABLE_SIGNALS();
  56. }
  57. void GC_register_displacement_inner(offset)
  58. word offset;
  59. {
  60. register unsigned i;
  61. word map_entry = BYTES_TO_WORDS(offset);
  62. if (offset >= VALID_OFFSET_SZ) {
  63. ABORT("Bad argument to GC_register_displacement");
  64. }
  65. if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
  66. if (!GC_valid_offsets[offset]) {
  67. GC_valid_offsets[offset] = TRUE;
  68. GC_modws_valid_offsets[offset % sizeof(word)] = TRUE;
  69. if (!GC_all_interior_pointers) {
  70. for (i = 0; i <= MAXOBJSZ; i++) {
  71. if (GC_obj_map[i] != 0) {
  72. if (i == 0) {
  73. GC_obj_map[i][offset] = (map_entry_type)map_entry;
  74. } else {
  75. register unsigned j;
  76. register unsigned lb = WORDS_TO_BYTES(i);
  77. if (offset < lb) {
  78. for (j = offset; j < HBLKSIZE; j += lb) {
  79. GC_obj_map[i][j] = (map_entry_type)map_entry;
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }
  86. }
  87. }
  88. /* Add a heap block map for objects of size sz to obj_map. */
  89. /* Return FALSE on failure. */
  90. GC_bool GC_add_map_entry(sz)
  91. word sz;
  92. {
  93. register unsigned obj_start;
  94. register unsigned displ;
  95. register map_entry_type * new_map;
  96. word map_entry;
  97. if (sz > MAXOBJSZ) sz = 0;
  98. if (GC_obj_map[sz] != 0) {
  99. return(TRUE);
  100. }
  101. new_map = (map_entry_type *)GC_scratch_alloc(MAP_SIZE);
  102. if (new_map == 0) return(FALSE);
  103. # ifdef PRINTSTATS
  104. GC_printf1("Adding block map for size %lu\n", (unsigned long)sz);
  105. # endif
  106. for (displ = 0; displ < HBLKSIZE; displ++) {
  107. MAP_ENTRY(new_map,displ) = OBJ_INVALID;
  108. }
  109. if (sz == 0) {
  110. for(displ = 0; displ <= HBLKSIZE; displ++) {
  111. if (OFFSET_VALID(displ)) {
  112. map_entry = BYTES_TO_WORDS(displ);
  113. if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
  114. MAP_ENTRY(new_map,displ) = (map_entry_type)map_entry;
  115. }
  116. }
  117. } else {
  118. for (obj_start = 0;
  119. obj_start + WORDS_TO_BYTES(sz) <= HBLKSIZE;
  120. obj_start += WORDS_TO_BYTES(sz)) {
  121. for (displ = 0; displ < WORDS_TO_BYTES(sz); displ++) {
  122. if (OFFSET_VALID(displ)) {
  123. map_entry = BYTES_TO_WORDS(displ);
  124. if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
  125. MAP_ENTRY(new_map, obj_start + displ) =
  126. (map_entry_type)map_entry;
  127. }
  128. }
  129. }
  130. }
  131. GC_obj_map[sz] = new_map;
  132. return(TRUE);
  133. }