00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 # include "gc_private.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 # define LOG_HT_ENTRIES 14
00034
00035
00036 # define HT_ENTRIES ((word)1 << LOG_HT_ENTRIES)
00037 # define HT_SIZE (HT_ENTRIES >> LOGWL)
00038 typedef word black_list_t[HT_SIZE];
00039
00040 # define HASH(addr) (((addr) >> LOG_HBLKSIZE) & (HT_ENTRIES - 1))
00041
00042
00043
00044 word * GC_new_normal_bl;
00045
00046
00047 word * GC_old_normal_bl;
00048
00049
00050 word * GC_incomplete_normal_bl;
00051
00052
00053 word * GC_new_stack_bl;
00054 word * GC_old_stack_bl;
00055 word * GC_incomplete_stack_bl;
00056
00057 # define get_bl_entry_from_index(bl, index) \
00058 (((bl)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)
00059 # define set_bl_entry_from_index(bl, index) \
00060 (bl)[divWORDSZ(index)] |= 1 << modWORDSZ(index)
00061 # define clear_bl_entry_from_index(bl, index) \
00062 (bl)[divWORDSZ(index)] &= ~(1 << modWORDSZ(index))
00063
00064 GC_bl_init()
00065 {
00066 # ifndef ALL_INTERIOR_POINTERS
00067 GC_new_normal_bl = (word *)GC_scratch_alloc((word)(sizeof(black_list_t)));
00068 GC_old_normal_bl = (word *)GC_scratch_alloc((word)(sizeof (black_list_t)));
00069 GC_incomplete_normal_bl = (word *)GC_scratch_alloc
00070 ((word)(sizeof(black_list_t)));
00071 # endif
00072 GC_new_stack_bl = (word *)GC_scratch_alloc((word)(sizeof(black_list_t)));
00073 GC_old_stack_bl = (word *)GC_scratch_alloc((word)(sizeof(black_list_t)));
00074 GC_incomplete_stack_bl = (word *)GC_scratch_alloc
00075 ((word)(sizeof(black_list_t)));
00076 }
00077
00078 void GC_clear_bl(doomed)
00079 word *doomed;
00080 {
00081 bzero((char *)doomed, (int)HT_SIZE*sizeof(word));
00082 }
00083
00084
00085
00086 void GC_promote_black_lists()
00087 {
00088 word * very_old_normal_bl = GC_old_normal_bl;
00089 word * very_old_stack_bl = GC_old_stack_bl;
00090
00091 GC_old_normal_bl = GC_new_normal_bl;
00092 GC_new_normal_bl = GC_incomplete_normal_bl;
00093 GC_old_stack_bl = GC_new_stack_bl;
00094 GC_new_stack_bl = GC_incomplete_stack_bl;
00095 # ifndef ALL_INTERIOR_POINTERS
00096 GC_clear_bl(very_old_normal_bl);
00097 # endif
00098 GC_clear_bl(very_old_stack_bl);
00099 GC_incomplete_normal_bl = very_old_normal_bl;
00100 GC_incomplete_stack_bl = very_old_stack_bl;
00101 }
00102
00103 # ifndef ALL_INTERIOR_POINTERS
00104
00105
00106
00107 void GC_add_to_black_list_normal(p)
00108 word p;
00109 {
00110 if (!(GC_modws_valid_offsets[p & (sizeof(word)-1)])) return;
00111 {
00112 register int index = HASH(p);
00113
00114 if (HDR(p) == 0 || get_bl_entry_from_index(GC_new_normal_bl, index)) {
00115 # ifdef PRINTBLACKLIST
00116 if (!get_bl_entry_from_index(GC_incomplete_normal_bl, index)) {
00117 GC_printf1("Black listing (normal) 0x%lx\n",
00118 (unsigned long) p);
00119 }
00120 # endif
00121 set_bl_entry_from_index(GC_incomplete_normal_bl, index);
00122 }
00123
00124 }
00125 }
00126 # endif
00127
00128
00129 void GC_add_to_black_list_stack(p)
00130 word p;
00131 {
00132 register int index = HASH(p);
00133
00134 if (HDR(p) == 0 || get_bl_entry_from_index(GC_new_stack_bl, index)) {
00135 # ifdef PRINTBLACKLIST
00136 if (!get_bl_entry_from_index(GC_incomplete_stack_bl, index)) {
00137 GC_printf1("Black listing (stack) 0x%lx\n",
00138 (unsigned long)p);
00139 }
00140 # endif
00141 set_bl_entry_from_index(GC_incomplete_stack_bl, index);
00142 }
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 struct hblk * GC_is_black_listed(h, len)
00154 struct hblk * h;
00155 word len;
00156 {
00157 register int index = HASH((word)h);
00158 register word i;
00159 word nblocks = divHBLKSZ(len);
00160
00161 # ifndef ALL_INTERIOR_POINTERS
00162 if (get_bl_entry_from_index(GC_new_normal_bl, index)
00163 && get_bl_entry_from_index(GC_old_normal_bl, index)) {
00164 return(h+1);
00165 }
00166 # endif
00167
00168 for (i = 0; ; ) {
00169 if (GC_new_stack_bl[divWORDSZ(index)] == 0) {
00170
00171 i += WORDSZ - modWORDSZ(index);
00172 } else {
00173 if (get_bl_entry_from_index(GC_new_stack_bl, index)
00174 && get_bl_entry_from_index(GC_old_stack_bl, index)) {
00175 return(h+i+1);
00176 }
00177 i++;
00178 }
00179 if (i >= nblocks) break;
00180 index = HASH((word)(h+i));
00181 }
00182 return(0);
00183 }
00184