pike.git / src / builtin_functions.c

version» Context lines:

pike.git/src/builtin_functions.c:7602: Inside #if defined(DEBUG_MALLOC)
   COUNT(memloc);    COUNT(memhdr);    }   #endif       call_callback(&memory_usage_callback, NULL);       f_aggregate_mapping(DO_NOT_WARN(Pike_sp - ss));   }    - /* estimate the size of an svalue, not including objects. -  this is used from size_object + /* Estimate the size of an svalue, not including objects. +  this is used from size_object. +  +  It should not include the size of the svalue itself, so the basic +  types count as 0 bytes. +  +  This is an estimate mainly because it is very hard to know to whom +  a certain array/mapping/multiset or string "belongs". +  +  The returned size will be the memory usage of the svalue divided by +  the number of references to it.   */ - static unsigned int rec_size_svalue( struct svalue *s, struct mapping **m ) +  + struct string_header   { -  +  PIKE_STRING_CONTENTS; + }; +  + unsigned int rec_size_svalue( struct svalue *s, struct mapping **m ) + {    unsigned int res = 0;    int i;    ptrdiff_t node_ref;    INT32 e; -  +  struct svalue *x;    struct keypair *k;       switch( s->type )    {    case PIKE_T_STRING:    /* FIXME: This makes assumptions about the threshold for short strings. */    if( s->u.string->flags & STRING_IS_SHORT ) -  return 16 / s->u.string->refs; +  return (16+sizeof(struct string_header)) / s->u.string->refs;    return ((s->u.string->len << s->u.string->size_shift) + -  sizeof(struct pike_string)) / s->u.string->refs; +  sizeof(struct string_header)) / s->u.string->refs;    case PIKE_T_INT:    case PIKE_T_OBJECT:    case PIKE_T_FLOAT:    case PIKE_T_FUNCTION:    case PIKE_T_TYPE:    return 0;    } -  +  if( !m ) return 0;       if( !*m )    *m = allocate_mapping( 10 ); -  else if( low_mapping_lookup( *m, s ) ) -  return 0; // already counted. +  else if( (x = low_mapping_lookup( *m, s )) ) +  { +  /* Already counted. Use the old size. */ +  return x->u.integer; +  }       low_mapping_insert( *m, s, &svalue_int_one, 0 );    switch( s->type )    {    case PIKE_T_ARRAY:    res = sizeof( struct array );    for( i=0; i<s->u.array->size; i++ )    res += sizeof(struct svalue) + rec_size_svalue( s->u.array->item+i, m );    break;       case PIKE_T_MULTISET: -  res = sizeof(struct multiset); +  res = sizeof(struct multiset) + sizeof(struct multiset_data);    node_ref = multiset_last( s->u.multiset );    while( node_ref != -1 )    {    res += rec_size_svalue( get_multiset_value (s->u.multiset, node_ref), m ) -  + sizeof(struct svalue); +  /* each node has the index and left/right node pointers. */ +  + sizeof(struct svalue) + (sizeof(void*)*2);    node_ref = multiset_prev( s->u.multiset, node_ref );    }    break;       case PIKE_T_MAPPING: -  res = sizeof(struct mapping) + sizeof(struct mapping_data); +  res = sizeof(struct mapping); +  { +  struct mapping_data *d = s->u.mapping->data; +  struct keypair *f = d->free_list; +  int data_size = sizeof( struct mapping_data ); +  data_size += d->hashsize * sizeof(struct keypair *) - sizeof(struct keypair *); +  while( f ) +  { +  data_size += sizeof(struct keypair); +  f = f->next; +  }    NEW_MAPPING_LOOP( s->u.mapping->data )    { -  res += rec_size_svalue( &k->ind, m ); -  res += rec_size_svalue( &k->val, m ); -  res += sizeof( struct keypair ); +  data_size += rec_size_svalue( &k->ind, m ); +  data_size += rec_size_svalue( &k->val, m ); +  data_size += sizeof( struct keypair );    } -  +  res += data_size / (d->hardlinks+1); +  }    break;    } -  return res / *s->u.refs; +  res /= *s->u.refs; +  low_mapping_lookup(*m,s)->u.integer = res; +  return res;   }      /*! @decl int size_object(object o)    *! @belongs Debug    *!    *! Return the aproximate size of the object, in bytes.    *! This might not work very well for native objects    *!    *!    *! The function tries to estimate the memory usage of variables