mark.h File Reference

Marking Primitives. More...

This graph shows which files directly or indirectly include this file:

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.

Detailed Description

Marking Primitives.

Definition in file mark.h.


Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

__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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:


Generated on Mon Jan 25 06:33:12 2010 for TM(tredmill) by  doxygen 1.6.1