Functions | |
void | tm_mark (void *ptr) |
Marks a possible pointer. | |
void | _tm_node_scan (tm_node *n) |
size_t | _tm_node_scan_some (size_t amount) |
Scan node interiors for some pointers. | |
void | _tm_node_scan_all () |
Scan until all tm_GREY nodes are tm_BLACK. |
void _tm_node_scan | ( | tm_node * | n | ) |
If the node was fully scanned, Move the tm_GREY node to the marked (tm_BLACK) list.
Definition at line 185 of file mark.c.
References _tm_range_scan(), tm_BLACK, tm_node_ptr, tm_node_set_color(), tm_node_to_block(), and tm_node_type.
00186 { 00187 _tm_range_scan(tm_node_ptr(n), tm_node_ptr(n) + tm_node_type(n)->size); 00188 00189 /** 00190 * If the node was fully scanned, 00191 * Move the tm_GREY node to the marked (tm_BLACK) list. 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 }
void _tm_node_scan_all | ( | ) |
Scan until all tm_GREY nodes are tm_BLACK.
Definition at line 291 of file mark.c.
References _tm_node_scan_some(), tm_GREY, and tm_node_LOOP_INIT.
Referenced by _tm_alloc_type_inner(), _tm_check_sweep_error(), and _tm_gc_full_type_inner().
00292 { 00293 tm_node_LOOP_INIT(tm_GREY); 00294 while ( _tm_node_scan_some(~ 0UL) ) { 00295 } 00296 }
size_t _tm_node_scan_some | ( | size_t | amount | ) |
Scan node interiors for some pointers.
Amount is in pointer-aligned words.
Until amount has been scanned, or nothing is left to scan.
If a there is a tm_node region to scan,
Scan until end of tm_node region,
Attempt to mark node at a possible pointer at the scan pointer,
And increment the current scan pointer.
Stop scanning if the given amount has been scanned.
If the node was fully scanned, Move the tm_GREY node to the marked (tm_BLACK) list.
Reset scan pointers.
Done scanning gi->scan_node.
If there is an tm_GREY node,
Schedule the now BLACK node for interior pointer scanning. Avoid words that overlap the end of the node's data region.
Return true if there are remaining tm_GREY nodes or some node is still being scanned.
Definition at line 207 of file mark.c.
References _tm_mark_possible_ptr(), gi, tm_data::n, tm, tm_assert_test, tm_BLACK, tm_GREY, tm_msg(), tm_node_color, tm_node_iterator_next(), tm_node_ptr, tm_node_set_color(), tm_node_to_block(), and tm_PTR_ALIGN.
Referenced by _tm_alloc_type_inner(), and _tm_node_scan_all().
00208 { 00209 size_t count = 0, bytes = 0; 00210 #define gi (&tm.node_color_iter[tm_GREY]) 00211 00212 /*! Until amount has been scanned, or nothing is left to scan. */ 00213 do { 00214 tm_node *n; 00215 00216 /** 00217 * If a there is a tm_node region to scan, 00218 */ 00219 if ( gi->scan_ptr ) { 00220 /*! Scan until end of tm_node region, */ 00221 while ( gi->scan_ptr <= gi->scan_end ) { 00222 /*! Attempt to mark node at a possible pointer at the scan pointer, */ 00223 _tm_mark_possible_ptr(* (void **) gi->scan_ptr); 00224 00225 /*! And increment the current scan pointer. */ 00226 gi->scan_ptr += tm_PTR_ALIGN; 00227 00228 ++ count; 00229 bytes += tm_PTR_ALIGN; 00230 00231 /*! Stop scanning if the given amount has been scanned. */ 00232 if ( -- amount <= 0 ) { 00233 goto done; 00234 } 00235 } 00236 00237 /** 00238 * If the node was fully scanned, 00239 * Move the tm_GREY node to the marked (tm_BLACK) list. 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 /*! Reset scan pointers. */ 00249 gi->scan_node = 0; 00250 gi->scan_ptr = 0; 00251 gi->scan_end = 0; 00252 gi->scan_size = 0; 00253 } 00254 /*! Done scanning gi->scan_node. */ 00255 00256 /*! If there is an tm_GREY node, */ 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 * Schedule the now BLACK node for interior pointer scanning. 00267 * Avoid words that overlap the end of the node's data region. 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 /*! Return true if there are remaining tm_GREY nodes or some node is still being scanned. */ 00285 return tm.n[tm_GREY] || gi->scan_size; 00286 }
void tm_mark | ( | void * | ptr | ) |
Marks a possible pointer.
tm_root_write() should be called after modifing a root ptr.
Definition at line 179 of file mark.c.
References _tm_mark_possible_ptr().
00180 { 00181 _tm_mark_possible_ptr(ptr); 00182 }