Ejemplo n.º 1
0
region newsubregion(region parent)
{
  // fprintf(stderr, "## newsubregion\n");
  char *first;
  region r;

  first = (char *)alloc_single_page(NULL);
  preclear(first + PAGE_HEADER_SIZE, RPAGESIZE - PAGE_HEADER_SIZE);

#ifdef STAGGER_RSTART
  /* stagger regions across cache lines a bit */
  rstart += 64;
#if RPAGESIZE < 1024
#error RPAGESIZE must be at least 1024, or change the next if.
#endif
  if (rstart >= 16 * 64) rstart = 0;
#endif
  r = (region)(first + rstart + PAGE_HEADER_SIZE);
  VALGRIND_MAKE_WRITABLE(r, sizeof(*r));
  postclear(r, sizeof *r);
  initregion(r);

  if (parent)
    link_region(r, parent);

  // fprintf(stderr, "## create mempool %p\n", r);
  VALGRIND_CREATE_MEMPOOL(r, 0, 0);
  ++num_regions_active;
  ++num_regions_created;
  return r;
}
Ejemplo n.º 2
0
// recursively propagate descendent count and max depth upwards
// r->visit_counter is incremented each time we have an opportunity
// to traverse to a parent. we only actually visit it once the visit
// counter reaches adjacent_region_count - 1 i.e. that we have already
// visited all of its other children
// as we travel upwards we collect nodes with the constraints defined by
// min_target_root_descendent_count, max_target_root_descendent_count,
// min_depth and max_depth
// we never traverse above a node which exceeds these constraints. we also
// never traverse nodes which are saturated or fragmented because it is
// ambiguous whether such a node has a parent, or if all it's children are
// attched, and we can't determine this in a single pass (we could save a list
// of these nodes for a later pass but we don't bother.)
// during the calls to this function we store the maximum leaf-to-node depth
// in r->depth, later this field has a different meaning
static void propagate_descendent_count_and_max_depth_upwards(
        Segmenter *s, Region *r, FidtrackerX *ft)
{
    int i;
    Region *parent = 0;

    assert( r->level == NOT_TRAVERSED );
    assert( r->children_visited_count == (r->adjacent_region_count - 1)         // has an untraversed parent 
            || r->children_visited_count == r->adjacent_region_count );   // is adjacent to root region

    r->descendent_count = 0;
    r->depth = 0;
    r->level = TRAVERSING;

    for( i=0; i < r->adjacent_region_count; ++i ){
        Region *adjacent = r->adjacent_regions[i];
        assert( r1_adjacent_contains_r2( adjacent, r ) );

        if( adjacent->level == TRAVERSED ){
            r->descendent_count += (short)(adjacent->descendent_count + 1);
            r->depth = (short)MAX( r->depth, (adjacent->depth + 1) );
        }else{
            assert( parent == 0 );
            parent = adjacent;
        }
    }

    r->level = TRAVERSED;

    if( r->descendent_count == ft->max_target_root_descendent_count
            && r->depth >= ft->min_depth && r->depth <= ft->max_depth ){

        // found fiducial candidate
        link_region( &ft->root_regions_head, r );
    }else{

        if( r->descendent_count >= ft->min_target_root_descendent_count
            && r->descendent_count < ft->max_target_root_descendent_count
            && r->depth >= ft->min_depth && r->depth <= ft->max_depth ) {
				link_region( &ft->root_regions_head, r );
       } else if( r->descendent_count >= ft->min_target_root_descendent_count-3
            && r->descendent_count < ft->max_target_root_descendent_count+3
            && r->depth >= ft->min_depth-1 && r->depth <= ft->max_depth+1 ) {
				r->flags |= LOST_SYMBOL_FLAG;
				link_region( &ft->root_regions_head, r );
       }
  

        if( parent
                && !(r->flags & (   SATURATED_REGION_FLAG |
                                    ADJACENT_TO_ROOT_REGION_FLAG |
                                    FREE_REGION_FLAG ) ) ){
        

            ++parent->children_visited_count;

            if( r->descendent_count < ft->max_target_root_descendent_count
                    && r->depth < ft->max_depth ){

                // continue propagating depth and descendent count upwards
                // so long as parent isn't a saturated node in which case it is
                // ambiguous whether parent has a parent or not so we skip it

                if(
                    !(parent->flags & SATURATED_REGION_FLAG)
                    &&
                    ( ( (!(parent->flags & (ADJACENT_TO_ROOT_REGION_FLAG | FRAGMENTED_REGION_FLAG) )
                        && parent->children_visited_count == (parent->adjacent_region_count - 1))
                    ||
                    ((parent->flags & (ADJACENT_TO_ROOT_REGION_FLAG | FRAGMENTED_REGION_FLAG) )
                        && parent->children_visited_count == parent->adjacent_region_count) ) )
                        ){

                    assert( r1_adjacent_contains_r2( r, parent ) );
                    assert( r1_adjacent_contains_r2( parent, r ) );

                    propagate_descendent_count_and_max_depth_upwards( s, parent, ft);
                }
            }
        }
    }
}