Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
mark_rts.c File Reference
#include <stdio.h>
#include "gc_priv.h"

Go to the source code of this file.

Functions

void GC_print_static_roots ()
GC_bool GC_is_static_root (ptr_t p)
static int rt_hash (char *addr)
struct rootsGC_roots_present (char *b)
static void add_roots_to_index (struct roots *p)
void GC_add_roots (char *b, char *e)
void GC_add_roots_inner (char *b, char *e, GC_bool tmp)
void GC_remove_roots (char *b, char *e)
void GC_remove_roots_inner (char *b, char *e)
void GC_clear_roots GC_PROTO ((void))
void GC_remove_tmp_roots ()
ptr_t GC_approx_sp ()
struct exclusionGC_next_exclusion (ptr_t start_addr)
void GC_exclude_static_roots (GC_PTR start, GC_PTR finish)
void GC_push_conditional_with_exclusions (ptr_t bottom, ptr_t top, int all)
void GC_push_current_stack (ptr_t cold_gc_frame)
void GC_push_roots (GC_bool all, ptr_t cold_gc_frame)

Variables

static int n_root_sets = 0
word GC_root_size = 0
size_t GC_excl_table_entries = 0

Function Documentation

static void add_roots_to_index ( struct roots p) [static]

Definition at line 131 of file mark_rts.c.

{
    register int h = rt_hash(p -> r_start);
    
    p -> r_next = GC_root_index[h];
    GC_root_index[h] = p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_add_roots ( char *  b,
char *  e 
)

Definition at line 151 of file mark_rts.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_add_roots_inner ( char *  b,
char *  e,
GC_bool  tmp 
)

Definition at line 169 of file mark_rts.c.

{
    struct roots * old;
    
#   ifdef MSWIN32
      /* Spend the time to ensure that there are no overlapping       */
      /* or adjacent intervals.                                */
      /* This could be done faster with e.g. a                 */
      /* balanced tree.  But the execution time here is        */
      /* virtually guaranteed to be dominated by the time it   */
      /* takes to scan the roots.                       */
      {
        register int i;
        
        for (i = 0; i < n_root_sets; i++) {
            old = GC_static_roots + i;
            if ((ptr_t)b <= old -> r_end && (ptr_t)e >= old -> r_start) {
                if ((ptr_t)b < old -> r_start) {
                    old -> r_start = (ptr_t)b;
                    GC_root_size += (old -> r_start - (ptr_t)b);
                }
                if ((ptr_t)e > old -> r_end) {
                    old -> r_end = (ptr_t)e;
                    GC_root_size += ((ptr_t)e - old -> r_end);
                }
                old -> r_tmp &= tmp;
                break;
            }
        }
        if (i < n_root_sets) {
          /* merge other overlapping intervals */
            struct roots *other;
            
            for (i++; i < n_root_sets; i++) {
              other = GC_static_roots + i;
              b = (char *)(other -> r_start);
              e = (char *)(other -> r_end);
              if ((ptr_t)b <= old -> r_end && (ptr_t)e >= old -> r_start) {
                if ((ptr_t)b < old -> r_start) {
                    old -> r_start = (ptr_t)b;
                    GC_root_size += (old -> r_start - (ptr_t)b);
                }
                if ((ptr_t)e > old -> r_end) {
                    old -> r_end = (ptr_t)e;
                    GC_root_size += ((ptr_t)e - old -> r_end);
                }
                old -> r_tmp &= other -> r_tmp;
                /* Delete this entry. */
                  GC_root_size -= (other -> r_end - other -> r_start);
                  other -> r_start = GC_static_roots[n_root_sets-1].r_start;
                  other -> r_end = GC_static_roots[n_root_sets-1].r_end;
                                  n_root_sets--;
              }
            }
          return;
        }
      }
#   else
      old = GC_roots_present(b);
      if (old != 0) {
        if ((ptr_t)e <= old -> r_end) /* already there */ return;
        /* else extend */
        GC_root_size += (ptr_t)e - old -> r_end;
        old -> r_end = (ptr_t)e;
        return;
      }
#   endif
    if (n_root_sets == MAX_ROOT_SETS) {
        ABORT("Too many root sets\n");
    }
    GC_static_roots[n_root_sets].r_start = (ptr_t)b;
    GC_static_roots[n_root_sets].r_end = (ptr_t)e;
    GC_static_roots[n_root_sets].r_tmp = tmp;
#   ifndef MSWIN32
      GC_static_roots[n_root_sets].r_next = 0;
#   endif
    add_roots_to_index(GC_static_roots + n_root_sets);
    GC_root_size += (ptr_t)e - (ptr_t)b;
    n_root_sets++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 337 of file mark_rts.c.

{
    word dummy;
    
    return((ptr_t)(&dummy));
}

Here is the caller graph for this function:

void GC_exclude_static_roots ( GC_PTR  start,
GC_PTR  finish 
)

Definition at line 383 of file mark_rts.c.

{
    struct exclusion * next;
    size_t next_index, i;

    if (0 == GC_excl_table_entries) {
       next = 0;
    } else {
       next = GC_next_exclusion(start);
    }
    if (0 != next) {
      if ((word)(next -> e_start) < (word) finish) {
       /* incomplete error check. */
       ABORT("exclusion ranges overlap");
      }  
      if ((word)(next -> e_start) == (word) finish) {
        /* extend old range backwards     */
          next -> e_start = (ptr_t)start;
         return;
      }
      next_index = next - GC_excl_table;
      for (i = GC_excl_table_entries; i > next_index; --i) {
       GC_excl_table[i] = GC_excl_table[i-1];
      }
    } else {
      next_index = GC_excl_table_entries;
    }
    if (GC_excl_table_entries == MAX_EXCLUSIONS) ABORT("Too many exclusions");
    GC_excl_table[next_index].e_start = (ptr_t)start;
    GC_excl_table[next_index].e_end = (ptr_t)finish;
    ++GC_excl_table_entries;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 69 of file mark_rts.c.

{
    static int last_root_set = 0;
    register int i;
    
    
    if (p >= GC_static_roots[last_root_set].r_start
        && p < GC_static_roots[last_root_set].r_end) return(TRUE);
    for (i = 0; i < n_root_sets; i++) {
       if (p >= GC_static_roots[i].r_start
            && p < GC_static_roots[i].r_end) {
            last_root_set = i;
            return(TRUE);
        }
    }
    return(FALSE);
}
struct exclusion* GC_next_exclusion ( ptr_t  start_addr) [read]

Definition at line 363 of file mark_rts.c.

{
    size_t low = 0;
    size_t high = GC_excl_table_entries - 1;
    size_t mid;

    while (high > low) {
       mid = (low + high) >> 1;
       /* low <= mid < high */
       if ((word) GC_excl_table[mid].e_end <= (word) start_addr) {
           low = mid + 1;
       } else {
           high = mid;
       }
    }
    if ((word) GC_excl_table[low].e_end <= (word) start_addr) return 0;
    return GC_excl_table + low;
}

Here is the caller graph for this function:

Definition at line 42 of file mark_rts.c.

{
    register int i;
    size_t total = 0;
    
    for (i = 0; i < n_root_sets; i++) {
        GC_printf2("From 0x%lx to 0x%lx ",
                 (unsigned long) GC_static_roots[i].r_start,
                 (unsigned long) GC_static_roots[i].r_end);
        if (GC_static_roots[i].r_tmp) {
            GC_printf0(" (temporary)\n");
        } else {
            GC_printf0("\n");
        }
        total += GC_static_roots[i].r_end - GC_static_roots[i].r_start;
    }
    GC_printf1("Total size: %ld\n", (unsigned long) total);
    if (GC_root_size != total) {
       GC_printf1("GC_root_size incorrect: %ld!!\n",
                 (unsigned long) GC_root_size);
    }
}

Here is the caller graph for this function:

void GC_clear_roots GC_PROTO ( (void )

Definition at line 289 of file mark_rts.c.

{
    DCL_LOCK_STATE;
    
    DISABLE_SIGNALS();
    LOCK();
    n_root_sets = 0;
    GC_root_size = 0;
#   ifndef MSWIN32
    {
       register int i;
       
       for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
    }
#   endif
    UNLOCK();
    ENABLE_SIGNALS();
}
void GC_push_conditional_with_exclusions ( ptr_t  bottom,
ptr_t  top,
int  all 
)

Definition at line 419 of file mark_rts.c.

{
    struct exclusion * next;
    ptr_t excl_start;

    while (bottom < top) {
        next = GC_next_exclusion(bottom);
       if (0 == next || (excl_start = next -> e_start) >= top) {
           GC_push_conditional(bottom, top, all);
           return;
       }
       if (excl_start > bottom) GC_push_conditional(bottom, excl_start, all);
       bottom = next -> e_end;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_push_current_stack ( ptr_t  cold_gc_frame)

Definition at line 444 of file mark_rts.c.

{
#   if defined(THREADS)
       if (0 == cold_gc_frame) return;
#       ifdef STACK_GROWS_DOWN
         GC_push_all_eager(GC_approx_sp(), cold_gc_frame);
#       else
         GC_push_all_eager( cold_gc_frame, GC_approx_sp() );
#       endif
#   else
#      ifdef STACK_GROWS_DOWN
           GC_push_all_stack_partially_eager( GC_approx_sp(), GC_stackbottom,
                                          cold_gc_frame );
#       else
           GC_push_all_stack_partially_eager( GC_stackbottom, GC_approx_sp(),
                                          cold_gc_frame );
#       endif
#   endif /* !THREADS */
}

Here is the call graph for this function:

void GC_push_roots ( GC_bool  all,
ptr_t  cold_gc_frame 
)

Definition at line 474 of file mark_rts.c.

{
    register int i;

    /*
     * push registers - i.e., call GC_push_one(r) for each
     * register contents r.
     */
#   ifdef USE_GENERIC_PUSH_REGS
       GC_generic_push_regs(cold_gc_frame);
#   else
        GC_push_regs(); /* usually defined in machine_dep.c */
#   endif
        
    /*
     * Next push static data.  This must happen early on, since it's
     * not robust against mark stack overflow.
     */
     /* Reregister dynamic libraries, in case one got added.   */
#      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
           && !defined(SRC_M3)
         GC_remove_tmp_roots();
         if (GC_root_size)
             GC_register_dynamic_libraries();
#      endif
     /* Mark everything in static data areas                             */
       for (i = 0; i < n_root_sets; i++) {
         GC_push_conditional_with_exclusions(
                          GC_static_roots[i].r_start,
                          GC_static_roots[i].r_end, all);
       }

    /*
     * Now traverse stacks.
     */
#   if !defined(USE_GENERIC_PUSH_REGS)
       GC_push_current_stack(cold_gc_frame);
       /* IN the threads case, this only pushes collector frames.      */
       /* In the USE_GENERIC_PUSH_REGS case, this is done inside      */
       /* GC_push_regs, so that we catch callee-save registers saved  */
       /* inside the GC_push_regs frame.                       */
#   endif
    if (GC_push_other_roots != 0) (*GC_push_other_roots)();
       /* In the threads case, this also pushes thread stacks. */
}

Here is the call graph for this function:

void GC_remove_roots ( char *  b,
char *  e 
)

Definition at line 252 of file mark_rts.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_remove_roots_inner ( char *  b,
char *  e 
)

Definition at line 264 of file mark_rts.c.

{
    register int i;
    
    for (i = 0; i < n_root_sets; ) {
       if (GC_static_roots[i].r_start == (ptr_t)b && GC_static_roots[i].r_end == (ptr_t)e) {
           GC_root_size -=
              (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
           GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
           GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
           GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
           n_root_sets--;
       } else {
           i++;
       }
    }
#   ifndef MSWIN32
    /* rehash the root table. */
    for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
    for (i = 0; i < n_root_sets; i++)
        add_roots_to_index(GC_static_roots + i);
#   endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 309 of file mark_rts.c.

{
    register int i;
    
    for (i = 0; i < n_root_sets; ) {
       if (GC_static_roots[i].r_tmp) {
           GC_root_size -=
              (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
           GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
           GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
           GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
           n_root_sets--;
       } else {
           i++;
       }
    }
#   ifndef MSWIN32
    {
       register int i;
       
       for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
       for (i = 0; i < n_root_sets; i++)
              add_roots_to_index(GC_static_roots + i);
    }
#   endif
    
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct roots* GC_roots_present ( char *  b) [read]

Definition at line 117 of file mark_rts.c.

{
    register int h = rt_hash(b);
    register struct roots *p = GC_root_index[h];
    
    while (p != 0) {
        if (p -> r_start == (ptr_t)b) return(p);
        p = p -> r_next;
    }
    return(FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rt_hash ( char *  addr) [static]

Definition at line 99 of file mark_rts.c.

{
    word result = (word) addr;
#   if CPP_WORDSZ > 8*LOG_RT_SIZE
       result ^= result >> 8*LOG_RT_SIZE;
#   endif
#   if CPP_WORDSZ > 4*LOG_RT_SIZE
       result ^= result >> 4*LOG_RT_SIZE;
#   endif
    result ^= result >> 2*LOG_RT_SIZE;
    result ^= result >> LOG_RT_SIZE;
    result &= (RT_SIZE-1);
    return(result);
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 358 of file mark_rts.c.

Definition at line 149 of file mark_rts.c.

int n_root_sets = 0 [static]

Definition at line 36 of file mark_rts.c.