00001
00002
00003
00004 #include "internal.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 __inline
00015 void _tm_range_scan(const void *b, const void *e)
00016 {
00017 const char *p;
00018
00019
00020 e = ((char *) e) - sizeof(void*);
00021
00022 for ( p = b;
00023 (char*) p <= (char*) e;
00024 p += tm_PTR_ALIGN ) {
00025 #if 0
00026 tm_node *n =
00027 #endif
00028 _tm_mark_possible_ptr(* (void**) p);
00029
00030 #if 0
00031 if ( n ) {
00032 tm_msg("M n%p p%p\n", n, p);
00033 }
00034 #endif
00035 }
00036 }
00037
00038
00039
00040 long tm_root_scan_some_size = 512;
00041
00042
00043
00044
00045 void _tm_root_loop_init()
00046 {
00047 tm.rooti = tm.root_datai;
00048 tm.rp = tm.roots[tm.rooti].l;
00049 tm.data_mutations = tm.stack_mutations = 0;
00050 }
00051
00052
00053
00054
00055
00056 static
00057 void _tm_root_scan_id(int i)
00058 {
00059 if ( tm.roots[i].l < tm.roots[i].h ) {
00060 tm_msg("r [%p,%p] %s\n", tm.roots[i].l, tm.roots[i].h, tm.roots[i].name);
00061 _tm_range_scan(tm.roots[i].l, tm.roots[i].h);
00062 }
00063 }
00064
00065
00066
00067
00068
00069
00070 void _tm_register_scan()
00071 {
00072 _tm_root_scan_id(0);
00073 }
00074
00075
00076
00077
00078
00079
00080 void _tm_set_stack_ptr(void *stackvar)
00081 {
00082 *tm.stack_ptrp = (char*) stackvar - 64;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091 void _tm_stack_scan()
00092 {
00093 _tm_register_scan();
00094 _tm_root_scan_id(1);
00095 tm.stack_mutations = 0;
00096 }
00097
00098
00099
00100
00101
00102 void _tm_root_scan_all()
00103 {
00104 int i;
00105
00106 tm_msg("r G%lu B%lu {\n", tm.n[tm_GREY], tm.n[tm_BLACK]);
00107 for ( i = 0; tm.roots[i].name; ++ i ) {
00108 _tm_root_scan_id(i);
00109 }
00110 tm.data_mutations = tm.stack_mutations = 0;
00111 _tm_root_loop_init();
00112 #if 0
00113 tm_msg("r G%lu B%lu }\n", tm.n[tm_GREY], tm.n[tm_BLACK]);
00114 #endif
00115 }
00116
00117
00118
00119
00120
00121 int _tm_root_scan_some()
00122 {
00123 int result = 1;
00124 long left = tm_root_scan_some_size;
00125
00126 tm_msg("r G%lu B%lu {\n", tm.n[tm_GREY], tm.n[tm_BLACK]);
00127 tm_msg("r [%p,%p] %s\n",
00128 tm.roots[tm.rooti].l,
00129 tm.roots[tm.rooti].h,
00130 tm.roots[tm.rooti].name
00131 );
00132
00133 do {
00134
00135 while ( (void*) (tm.rp + sizeof(void*)) >= tm.roots[tm.rooti].h ) {
00136 ++ tm.rooti;
00137 if ( ! tm.roots[tm.rooti].name ) {
00138 _tm_root_loop_init();
00139 tm_msg("r done\n");
00140
00141 result = 0;
00142 goto done;
00143 }
00144
00145 tm_msg("r [%p,%p] %s\n",
00146 tm.roots[tm.rooti].l,
00147 tm.roots[tm.rooti].h,
00148 tm.roots[tm.rooti].name);
00149
00150 tm.rp = tm.roots[tm.rooti].l;
00151 }
00152
00153 _tm_mark_possible_ptr(* (void**) tm.rp);
00154
00155 tm.rp += tm_PTR_ALIGN;
00156 left -= tm_PTR_ALIGN;
00157
00158 } while ( left > 0 );
00159
00160 done:
00161 #if 0
00162 tm_msg("r G%lu B%lu }\n", tm.n[tm_GREY], tm.n[tm_BLACK]);
00163 #endif
00164
00165 return result;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 void tm_mark(void *ptr)
00180 {
00181 _tm_mark_possible_ptr(ptr);
00182 }
00183
00184
00185 void _tm_node_scan(tm_node *n)
00186 {
00187 _tm_range_scan(tm_node_ptr(n), tm_node_ptr(n) + tm_node_type(n)->size);
00188
00189
00190
00191
00192
00193 tm_node_set_color(n, tm_node_to_block(n), tm_BLACK);
00194
00195 #if 0
00196 fprintf(stderr, "[B]");
00197 fflush(stderr);
00198 #endif
00199 }
00200
00201
00202
00203
00204
00205
00206
00207 size_t _tm_node_scan_some(size_t amount)
00208 {
00209 size_t count = 0, bytes = 0;
00210 #define gi (&tm.node_color_iter[tm_GREY])
00211
00212
00213 do {
00214 tm_node *n;
00215
00216
00217
00218
00219 if ( gi->scan_ptr ) {
00220
00221 while ( gi->scan_ptr <= gi->scan_end ) {
00222
00223 _tm_mark_possible_ptr(* (void **) gi->scan_ptr);
00224
00225
00226 gi->scan_ptr += tm_PTR_ALIGN;
00227
00228 ++ count;
00229 bytes += tm_PTR_ALIGN;
00230
00231
00232 if ( -- amount <= 0 ) {
00233 goto done;
00234 }
00235 }
00236
00237
00238
00239
00240
00241 tm_node_set_color(gi->scan_node, tm_node_to_block(gi->scan_node), tm_BLACK);
00242
00243 #if 0
00244 fprintf(stderr, "B");
00245 fflush(stderr);
00246 #endif
00247
00248
00249 gi->scan_node = 0;
00250 gi->scan_ptr = 0;
00251 gi->scan_end = 0;
00252 gi->scan_size = 0;
00253 }
00254
00255
00256
00257 if ( (n = tm_node_iterator_next(gi)) ) {
00258 tm_assert_test(tm_node_color(n) == tm_GREY);
00259
00260 #if 0
00261 fprintf(stderr, "s");
00262 fflush(stderr);
00263 #endif
00264
00265
00266
00267
00268
00269 gi->scan_node = n;
00270 gi->scan_ptr = tm_node_ptr(n);
00271 gi->scan_size = gi->type->size;
00272 gi->scan_end = gi->scan_ptr + gi->scan_size - sizeof(void*);
00273 } else {
00274 goto done;
00275 }
00276 } while ( amount > 0 );
00277
00278 done:
00279 #if 0
00280 if ( count )
00281 tm_msg("M c%lu b%lu l%lu\n", count, bytes, tm.n[tm_GREY]);
00282 #endif
00283
00284
00285 return tm.n[tm_GREY] || gi->scan_size;
00286 }
00287
00288
00289
00290
00291 void _tm_node_scan_all()
00292 {
00293 tm_node_LOOP_INIT(tm_GREY);
00294 while ( _tm_node_scan_some(~ 0UL) ) {
00295 }
00296 }
00297
00298 #undef gi
00299
00300
00301