Marking Primitives. More...
Go to the source code of this file.
Functions | |
static __inline int | _tm_node_mark (tm_node *n) |
Marks a node as in-use. | |
static __inline tm_node * | _tm_mark_possible_ptr (void *p) |
Mark a potential pointer. | |
void | _tm_root_loop_init () |
Initialize root scanning loop. | |
void | _tm_register_scan () |
Scan registers. | |
void | _tm_set_stack_ptr (void *stackvar) |
Set the stack pointer. | |
void | _tm_stack_scan () |
Scan stack (and registers). | |
void | _tm_root_scan_all () |
Scan all roots. | |
int | _tm_root_scan_some () |
Scan some roots. | |
__inline void | _tm_range_scan (const void *b, const void *e) |
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. |
Marking Primitives.
Definition in file mark.h.
static __inline tm_node* _tm_mark_possible_ptr | ( | void * | p | ) | [static] |
Mark a potential pointer.
Returns true if something was marked.
Definition at line 71 of file mark.h.
References _tm_node_mark(), tm_data::n, and tm_ptr_to_node().
Referenced by _tm_node_scan_some(), _tm_range_scan(), _tm_root_scan_some(), and tm_mark().
00072 { 00073 tm_node *n; 00074 00075 if ( p && (n = tm_ptr_to_node(p)) && _tm_node_mark(n) ) 00076 return n; 00077 00078 return 0; 00079 }
static __inline int _tm_node_mark | ( | tm_node * | n | ) | [static] |
Marks a node as in-use.
If tm_WHITE, we have a spurious pointer into a free node? ABORT!
If tm_ECRU, the node has not been scheduled for marking; So schedule it for marking. Return true to alert caller that work is to be done.
If tm_GREY, the node has already been scheduled for marking. DO NOTHING.
If tm_BLACK, the node has already been marked. DO NOTHING.
Otherwise, return false: there is nothing to do.
Definition at line 16 of file mark.h.
References tm_abort(), tm_BLACK, tm_ECRU, tm_GREY, tm_msg(), tm_node_color, tm_node_set_color(), tm_node_to_block(), and tm_WHITE.
Referenced by _tm_mark_possible_ptr().
00017 { 00018 switch ( tm_node_color(n) ) { 00019 case tm_WHITE: 00020 /** If tm_WHITE, we have a spurious pointer into a free node? 00021 * ABORT! 00022 */ 00023 tm_abort(); 00024 break; 00025 00026 case tm_ECRU: 00027 /** 00028 * If tm_ECRU, 00029 * the node has not been scheduled for marking; 00030 * So schedule it for marking. 00031 * Return true to alert caller that work is to be done. 00032 */ 00033 tm_node_set_color(n, tm_node_to_block(n), tm_GREY); 00034 #if 0 00035 tm_msg("m n%p\n", n); 00036 #endif 00037 return 1; 00038 break; 00039 00040 case tm_GREY: 00041 /** 00042 * If tm_GREY, 00043 * the node has already been scheduled for marking. 00044 * DO NOTHING. 00045 */ 00046 break; 00047 00048 case tm_BLACK: 00049 /** 00050 * If tm_BLACK, 00051 * the node has already been marked. 00052 * DO NOTHING. 00053 */ 00054 break; 00055 00056 default: 00057 tm_abort(); 00058 break; 00059 } 00060 00061 /*! Otherwise, return false: there is nothing to do. */ 00062 return 0; 00063 }
__inline void _tm_range_scan | ( | const void * | b, | |
const void * | e | |||
) |
Definition at line 15 of file mark.c.
References _tm_mark_possible_ptr(), tm_data::n, tm_msg(), and tm_PTR_ALIGN.
Referenced by _tm_node_scan(), and _tm_root_scan_id().
00016 { 00017 const char *p; 00018 00019 /* Avoid overlapping pointer. */ 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 }
void _tm_register_scan | ( | ) |
Scan registers.
Registers are in tm.root[0].
Definition at line 70 of file mark.c.
References _tm_root_scan_id().
Referenced by _tm_stack_scan().
00071 { 00072 _tm_root_scan_id(0); 00073 }
void _tm_root_loop_init | ( | ) |
Initialize root scanning loop.
Definition at line 45 of file mark.c.
References tm_data::data_mutations, tm_root::l, tm_data::root_datai, tm_data::rooti, tm_data::roots, tm_data::rp, tm_data::stack_mutations, and tm.
Referenced by _tm_phase_init(), _tm_root_scan_all(), _tm_root_scan_some(), and tm_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 }
void _tm_root_scan_all | ( | ) |
Scan all roots.
Definition at line 102 of file mark.c.
References _tm_root_loop_init(), _tm_root_scan_id(), tm_data::data_mutations, tm_data::n, tm_root::name, tm_data::roots, tm_data::stack_mutations, tm, tm_BLACK, tm_GREY, and tm_msg().
Referenced by _tm_alloc_type_inner(), _tm_check_sweep_error(), and _tm_gc_full_type_inner().
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 }
int _tm_root_scan_some | ( | ) |
Scan some roots.
Definition at line 121 of file mark.c.
References _tm_mark_possible_ptr(), _tm_root_loop_init(), tm_root::h, tm_root::l, tm_data::n, tm_root::name, tm_data::rooti, tm_data::roots, tm_data::rp, tm, tm_BLACK, tm_GREY, tm_msg(), tm_PTR_ALIGN, and tm_root_scan_some_size.
Referenced by _tm_alloc_type_inner().
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 /* Try marking some roots. */ 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; /* We're not done. */ 00166 }
void _tm_stack_scan | ( | ) |
Scan stack (and registers).
Mark stack as un-mutated.
Definition at line 91 of file mark.c.
References _tm_register_scan(), _tm_root_scan_id(), tm_data::stack_mutations, and tm.
00092 { 00093 _tm_register_scan(); 00094 _tm_root_scan_id(1); 00095 tm.stack_mutations = 0; 00096 }